Android的ListView的头 [英] Android ListView headers

查看:189
本文介绍了Android的ListView的头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的ListView具有某种上的事件。事件由日排序,我想有时间就可以了头的每一天,然后在下面的事件监听。

下面是我如何填充该列表:

 的ArrayList< TwoText> CRS =新的ArrayList< TwoText>();

     crs.add(新TwoText(这将是头,event.getDate()));

     对于(活动事件:事件){
            crs.add(新TwoText(event.getStartString()+ - + event.getEndString(),event.getSubject()));
        }

       arrayAdapter =新TwoTextArrayAdapter(这一点,R.layout.my_list_item,CRS);
       lv1.setAdapter(arrayAdapter);
 

和这是我的类TwoText如下:

 公共类TwoText {
    公共字符串的classID;
    公共字符串状态;

    公共TwoText(字符串的classID,字符串州){
        this.classID =的classID;
        this.state =状态;
    }
}
 

和这是我的TwoTextArrayAdapter类的样子:

 进口的java.util.ArrayList;
进口android.app.Activity;
进口android.content.Context;
进口android.view.LayoutInflater;
进口android.view.View;
进口android.view.ViewGroup;
进口android.widget.ArrayAdapter;
进口android.widget.TextView;

公共类TwoTextArrayAdapter扩展ArrayAdapter< TwoText> {

    私人的ArrayList< TwoText>班;
    私人活动CON;
    TextView的分隔符;

    公共TwoTextArrayAdapter(活动的背景下,INT textViewResourceId,ArrayList的< TwoText>类){
        超(背景下,textViewResourceId,班);
        this.con =背景;
        this.classes =班;

    }

    @覆盖

    公共查看getView(INT位置,查看convertView,ViewGroup中父){

        视图V = convertView;

        如果(V == NULL){

            LayoutInflater VI =(LayoutInflater)con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            V = vi.inflate(R.layout.my_list_item,NULL);

        }

        TwoText用户= classes.get(位置);

        如果(用户!= NULL){

            TextView的内容1 =(TextView中)v.findViewById(R.id.list_content1);

            TextView的内容2 =(TextView中)v.findViewById(R.id.list_content2);

            如果(内容1!= NULL){

                content1.setText(user.classID);
            }
            如果(内容2!= NULL){

                content2.setText(user.state);
            }
        }
        返回伏;
    }
}
 

这是my_list_item.xml

 < XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:方向=垂直>

    <的TextView
        风格=机器人:ATTR / listSeparatorTextViewStyle
        机器人:ID =@ + ID /分离器
        机器人:文本=头
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =WRAP_CONTENT
        机器人:后台=#757678
        机器人:文字颜色=#f5c227/>

    <的LinearLayout
        的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent
        机器人:方向=横向>

        <的TextView
            机器人:ID =@ + ID / list_content1
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =match_parent
            机器人:layout_margin =5dip
            机器人:可点击=假
            机器人:重力=中心
            机器人:longClickable =假
            机器人:paddingBottom会=1dip
            机器人:paddingTop =1dip
            机器人:文本=样本
            机器人:文字颜色=#ff7f1d
            机器人:TEXTSIZE =17dip
            机器人:TEXTSTYLE =黑体/>

        <的TextView
            机器人:ID =@ + ID / list_content2
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =match_parent
            机器人:layout_margin =5dip
            机器人:可点击=假
            机器人:重力=中心
            机器人:linksClickable =假
            机器人:longClickable =假
            机器人:paddingBottom会=1dip
            机器人:paddingTop =1dip
            机器人:文本=样本
            机器人:文字颜色=#6d6d6d
            机器人:TEXTSIZE =17dip/>
    < / LinearLayout中>

< / LinearLayout中>
 

我做什么,此刻是我加入的头就像常规列表对象,但我还想它是作为标题,在我的情况下,有一个日期就可以了。

我有这个code。在我的XML的头:

 <的TextView
        风格=机器人:ATTR / listSeparatorTextViewStyle
        机器人:ID =@ + ID /分离器
        机器人:文本=头
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =WRAP_CONTENT
        机器人:后台=#757678
        机器人:文字颜色=#f5c227/>
 

和我试图隐藏它时,它是不必要的,并将其显示neccessary的时候,但我只是搞砸了我的code休息。我试过几个教程,但他们也有同样的效果。

任何人都可以指导我怎么做,简单的方法?

解决方案

下面是我如何做到这一点的关键是<一href="http://developer.android.com/reference/android/widget/Adapter.html#getItemViewType%28int%29">getItemViewType和<一href="http://developer.android.com/reference/android/widget/Adapter.html#getViewTypeCount%28%29">getViewTypeCount在适配器类。 getViewTypeCount 返回多少类型,我们在列表中的项目,在这种情况下,我们有一个头的项目和活动项目,让两种。 getItemViewType 应该返回什么类型的查看我们在输入位置

那么

Android将采取自动传递您在 convertView 的正确类型的查看的照顾。

下面是什么的code结果如下的样子:

首先,我们有一个接​​口,我们的两个列表项类型将执行

 公共接口项目{
    公众诠释getViewType();
    公共查看getView(LayoutInflater充气,查看convertView);
}
 

然后我们有一个适配器,需要项的列表

 公共类TwoTextArrayAdapter扩展ArrayAdapter&LT;项目&GT; {
    私人LayoutInflater mInflater;

    公共枚举ROWTYPE {
        list_item可,HEADER_ITEM
    }

    公共TwoTextArrayAdapter(上下文的背景下,列表与LT;项目&GT;项目){
        超(背景下,0项);
        mInflater = LayoutInflater.from(上下文);
    }

    @覆盖
    公众诠释getViewTypeCount(){
        返回RowType.values​​()的长度。

    }

    @覆盖
    公众诠释getItemViewType(INT位置){
        返回的getItem(位置).getViewType();
    }
 

  @覆盖
    公共查看getView(INT位置,查看convertView,ViewGroup中父){
        返回的getItem(位置).getView(mInflater,convertView);
    }
 

修改 更好地为性能..滚动时可以注意到

 私有静态最终诠释TYPE_ITEM = 0;私有静态最终诠释TYPE_SEPARATOR = 1;公共查看getView(INT位置,查看convertView,ViewGroup中父){
    ViewHolder支架=无效;
    INT ROWTYPE = getItemViewType(位置);
    查看查看;
    如果(convertView == NULL){
        持有人=新ViewHolder();
        开关(行类型){
            案例TYPE_ITEM:
                convertView = mInflater.inflate(R.layout.task_details_row,NULL);
                holder.View =的getItem(位置).getView(mInflater,convertView);
                打破;
            案例TYPE_SEPARATOR:
                convertView = mInflater.inflate(R.layout.task_detail_header,NULL);
                holder.View =的getItem(位置).getView(mInflater,convertView);
                打破;
        }
        convertView.setTag(保持器);
    }
    其他
    {
        支架=(ViewHolder)convertView.getTag();
    }
    返回convertView; }公共静态类ViewHolder {
    公共景观景观; }}
 

然后,我们班的实施项目和膨胀的正确布局。你的情况,你会碰到这样一个标题类和列表项类。

 公共类头实现项目{
    私人最终字符串名称;

    公共头(字符串名称){
        this.name =名称;
    }

    @覆盖
    公众诠释getViewType(){
        返回RowType.HEADER_ITEM.ordinal();
    }

    @覆盖
    公共查看getView(LayoutInflater充气,查看convertView){
        查看图。
        如果(convertView == NULL){
            鉴于=(查看)inflater.inflate(R.layout.header,NULL);
            //做一些初始化
        } 其他 {
            鉴于= convertView;
        }

        TextView的文字=(TextView的)view.findViewById(R.id.separator);
        text.setText(名称);

        返回查看;
    }

}
 

然后在列表项

 公共类列表项实施项目{
    私人最终字符串STR1;
    私人最终字符串STR2;

    公共列表项(字符串文本1,字符串文本2){
        this.str1 =文本1;
        this.str2 =文本2;
    }

    @覆盖
    公众诠释getViewType(){
        返回RowType.LIST_ITEM.ordinal();
    }

    @覆盖
    公共查看getView(LayoutInflater充气,查看convertView){
        查看图。
        如果(convertView == NULL){
            鉴于=(查看)inflater.inflate(R.layout.my_list_item,NULL);
            //做一些初始化
        } 其他 {
            鉴于= convertView;
        }

        TextView的文本1 =(TextView中)view.findViewById(R.id.list_content1);
        TextView的文本2 =(TextView中)view.findViewById(R.id.list_content2);
        text1.setText(STR1);
        text2.setText(STR2);

        返回查看;
    }

}
 

和一个简单的活动来显示它

 公共类MainActivity扩展ListActivity {

    @覆盖
    保护无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);

        名单&LT;项目&GT;项目=新的ArrayList&LT;项目&GT;();
        items.add(新标题(标题1));
        items.add(新的ListItem(文本1,乌合之众乌合之众));
        items.add(新的ListItem(文本2,乌合之众乌合之众));
        items.add(新的ListItem(文本3,乌合之众乌合之众));
        items.add(新的ListItem(文本4,乌合之众乌合之众));
        items.add(新标题(标题2));
        items.add(新的ListItem(文本5,乌合之众乌合之众));
        items.add(新的ListItem(文本6,乌合之众乌合之众));
        items.add(新的ListItem(文字7,乌合之众乌合之众));
        items.add(新的ListItem(文本8,乌合之众乌合之众));

        TwoTextArrayAdapter适配器=新TwoTextArrayAdapter(这一点,项目);
        setListAdapter(适配器);
    }

}
 

布局 R.layout.header

 &LT; XML版本=1.0编码=UTF-8&GT?;
&LT; LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:方向=横向&GT;

    &LT;的TextView
        风格=机器人:ATTR / listSeparatorTextViewStyle
        机器人:ID =@ + ID /分离器
        机器人:文本=头
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =WRAP_CONTENT
        机器人:后台=#757678
        机器人:文字颜色=#f5c227/&GT;

&LT; / LinearLayout中&GT;
 

布局 R.layout.my_list_item

 &LT; XML版本=1.0编码=UTF-8&GT?;
&LT; LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:方向=横向&GT;

    &LT;的TextView
        机器人:ID =@ + ID / list_content1
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =match_parent
        机器人:layout_margin =5dip
        机器人:可点击=假
        机器人:重力=中心
        机器人:longClickable =假
        机器人:paddingBottom会=1dip
        机器人:paddingTop =1dip
        机器人:文本=样本
        机器人:文字颜色=#ff7f1d
        机器人:TEXTSIZE =17dip
        机器人:TEXTSTYLE =黑体/&GT;

    &LT;的TextView
        机器人:ID =@ + ID / list_content2
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =match_parent
        机器人:layout_margin =5dip
        机器人:可点击=假
        机器人:重力=中心
        机器人:linksClickable =假
        机器人:longClickable =假
        机器人:paddingBottom会=1dip
        机器人:paddingTop =1dip
        机器人:文本=样本
        机器人:文字颜色=#6d6d6d
        机器人:TEXTSIZE =17dip/&GT;

&LT; / LinearLayout中&GT;
 

布局 R.layout.activity_main.xml

 &LT; RelativeLayout的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    工具:上下文=MainActivity。&GT;

    &LT;的ListView
        机器人:ID =@机器人:ID /列表
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =FILL_PARENT/&GT;

&LT; / RelativeLayout的&GT;
 

您也可以更大胆,并使用 ViewHolders ,载异步的东西,或者你喜欢的。

I have ListView that has some kind of events on it. Events are sorted by day, and I would like to have header with date on it for every day, and then events listen below.

Here is how I populate that list:

ArrayList<TwoText> crs = new ArrayList<TwoText>();

     crs.add(new TwoText("This will be header",event.getDate()));

     for (Event event : events) {
            crs.add(new TwoText(event.getStartString()+"-"+event.getEndString(),event.getSubject()));
        }

       arrayAdapter = new TwoTextArrayAdapter(this,R.layout.my_list_item, crs);
       lv1.setAdapter(arrayAdapter);

and this is how my class TwoText looks:

public class TwoText {
    public String classID;
    public String state;

    public TwoText(String classID, String state) {
        this.classID = classID;
        this.state = state;
    }
}

and this is how my TwoTextArrayAdapter class looks:

import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class TwoTextArrayAdapter extends ArrayAdapter<TwoText> {

    private ArrayList<TwoText> classes;
    private Activity con;
    TextView seperator;

    public TwoTextArrayAdapter(Activity context, int textViewResourceId, ArrayList<TwoText> classes) {
        super(context, textViewResourceId, classes);
        this.con = context;
        this.classes = classes;

    }

    @Override

    public View getView(int position, View convertView, ViewGroup parent) {

        View v = convertView;

        if (v == null) {

            LayoutInflater vi = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            v = vi.inflate(R.layout.my_list_item, null);

        }

        TwoText user = classes.get(position);

        if (user != null) {

            TextView content1 = (TextView) v.findViewById(R.id.list_content1);

            TextView content2 = (TextView) v.findViewById(R.id.list_content2);

            if (content1 != null) {

                content1.setText(user.classID);
            }   
            if(content2 != null) {

                content2.setText(user.state);
            }
        }
        return v;
    }
}

and this is my_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        style="?android:attr/listSeparatorTextViewStyle"
        android:id="@+id/separator"
        android:text="Header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#757678"
        android:textColor="#f5c227" />

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/list_content1"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_margin="5dip"
            android:clickable="false"
            android:gravity="center"
            android:longClickable="false"
            android:paddingBottom="1dip"
            android:paddingTop="1dip"
            android:text="sample"
            android:textColor="#ff7f1d"
            android:textSize="17dip"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/list_content2"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_margin="5dip"
            android:clickable="false"
            android:gravity="center"
            android:linksClickable="false"
            android:longClickable="false"
            android:paddingBottom="1dip"
            android:paddingTop="1dip"
            android:text="sample"
            android:textColor="#6d6d6d"
            android:textSize="17dip" />
    </LinearLayout>

</LinearLayout>

what I do at the moment is that I am adding header just as regular list object, but Id like it to be as header and in my case have a date on it.

I have this code in my xml for header:

<TextView
        style="?android:attr/listSeparatorTextViewStyle"
        android:id="@+id/separator"
        android:text="Header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#757678"
        android:textColor="#f5c227" />

and I tried hiding it when it is unneccessary and showing it when neccessary but I just messed up rest of my code. I tried few more tutorials but they also had same effect.

Could anyone guide me on how to do that easy way?

解决方案

Here's how I do it, the keys are getItemViewType and getViewTypeCount in the Adapter class. getViewTypeCount returns how many types of items we have in the list, in this case we have a header item and an event item, so two. getItemViewType should return what type of View we have at the input position.

Android will then take care of passing you the right type of View in convertView automatically.

Here what the result of the code below looks like:

First we have an interface that our two list item types will implement

public interface Item {
    public int getViewType();
    public View getView(LayoutInflater inflater, View convertView);
}

Then we have an adapter that takes a list of Item

public class TwoTextArrayAdapter extends ArrayAdapter<Item> {
    private LayoutInflater mInflater;

    public enum RowType {
        LIST_ITEM, HEADER_ITEM
    }

    public TwoTextArrayAdapter(Context context, List<Item> items) {
        super(context, 0, items);
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getViewTypeCount() {
        return RowType.values().length;

    }

    @Override
    public int getItemViewType(int position) {
        return getItem(position).getViewType();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return getItem(position).getView(mInflater, convertView);
    }

EDIT Better For Performance.. can be noticed when scrolling

private static final int TYPE_ITEM = 0; private static final int TYPE_SEPARATOR = 1; public View getView(int position, View convertView, ViewGroup parent)  {
    ViewHolder holder = null;
    int rowType = getItemViewType(position);
    View View;
    if (convertView == null) {
        holder = new ViewHolder();
        switch (rowType) {
            case TYPE_ITEM:
                convertView = mInflater.inflate(R.layout.task_details_row, null);
                holder.View=getItem(position).getView(mInflater, convertView);
                break;
            case TYPE_SEPARATOR:
                convertView = mInflater.inflate(R.layout.task_detail_header, null);
                holder.View=getItem(position).getView(mInflater, convertView);
                break;
        }
        convertView.setTag(holder);
    }
    else
    {
        holder = (ViewHolder) convertView.getTag();
    }
    return convertView; } public static class ViewHolder {
    public  View View; } }

Then we have classes the implement Item and inflate the correct layouts. In your case you'll have something like a Header class and a ListItem class.

   public class Header implements Item {
    private final String         name;

    public Header(String name) {
        this.name = name;
    }

    @Override
    public int getViewType() {
        return RowType.HEADER_ITEM.ordinal();
    }

    @Override
    public View getView(LayoutInflater inflater, View convertView) {
        View view;
        if (convertView == null) {
            view = (View) inflater.inflate(R.layout.header, null);
            // Do some initialization
        } else {
            view = convertView;
        }

        TextView text = (TextView) view.findViewById(R.id.separator);
        text.setText(name);

        return view;
    }

}

And then the ListItem class

    public class ListItem implements Item {
    private final String         str1;
    private final String         str2;

    public ListItem(String text1, String text2) {
        this.str1 = text1;
        this.str2 = text2;
    }

    @Override
    public int getViewType() {
        return RowType.LIST_ITEM.ordinal();
    }

    @Override
    public View getView(LayoutInflater inflater, View convertView) {
        View view;
        if (convertView == null) {
            view = (View) inflater.inflate(R.layout.my_list_item, null);
            // Do some initialization
        } else {
            view = convertView;
        }

        TextView text1 = (TextView) view.findViewById(R.id.list_content1);
        TextView text2 = (TextView) view.findViewById(R.id.list_content2);
        text1.setText(str1);
        text2.setText(str2);

        return view;
    }

}

And a simple Activity to display it

public class MainActivity extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        List<Item> items = new ArrayList<Item>();
        items.add(new Header("Header 1"));
        items.add(new ListItem("Text 1", "Rabble rabble"));
        items.add(new ListItem("Text 2", "Rabble rabble"));
        items.add(new ListItem("Text 3", "Rabble rabble"));
        items.add(new ListItem("Text 4", "Rabble rabble"));
        items.add(new Header("Header 2"));
        items.add(new ListItem("Text 5", "Rabble rabble"));
        items.add(new ListItem("Text 6", "Rabble rabble"));
        items.add(new ListItem("Text 7", "Rabble rabble"));
        items.add(new ListItem("Text 8", "Rabble rabble"));

        TwoTextArrayAdapter adapter = new TwoTextArrayAdapter(this, items);
        setListAdapter(adapter);
    }

}

Layout for R.layout.header

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <TextView
        style="?android:attr/listSeparatorTextViewStyle"
        android:id="@+id/separator"
        android:text="Header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#757678"
        android:textColor="#f5c227" />

</LinearLayout>

Layout for R.layout.my_list_item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/list_content1"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dip"
        android:clickable="false"
        android:gravity="center"
        android:longClickable="false"
        android:paddingBottom="1dip"
        android:paddingTop="1dip"
        android:text="sample"
        android:textColor="#ff7f1d"
        android:textSize="17dip"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/list_content2"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dip"
        android:clickable="false"
        android:gravity="center"
        android:linksClickable="false"
        android:longClickable="false"
        android:paddingBottom="1dip"
        android:paddingTop="1dip"
        android:text="sample"
        android:textColor="#6d6d6d"
        android:textSize="17dip" />

</LinearLayout>

Layout for R.layout.activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</RelativeLayout>

You can also get fancier and use ViewHolders, load stuff asynchronously, or whatever you like.

这篇关于Android的ListView的头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆