【问题标题】:Android ListView with section headers and footers?带有部分页眉和页脚的Android ListView?
【发布时间】:2019-09-10 15:03:05
【问题描述】:

我想创建自定义列表,通过对我设法按数据类型获取每个节标题的数据进行分组,为每一行增加不同的数据,但我也想为每个节添加页脚。我不知道如何执行它

我试图通过 getitemviewtype() 返回部分页脚,但它必须在每个项目类型中返回,所以不知道如何执行它

public override View GetView(int position, View convertView, ViewGroup parent)
    {
        programTabAllItemHolder programTabAllItemHolder;
        View view = convertView;
        if (view == null)
        {
            programTabAllItemHolder = new programTabAllItemHolder();
            if (GetItemViewType(position) == 0)
            {
                view = LayoutInflater.From(context).Inflate(Resource.Layout.FTSProgramItemLayout, parent, false);
                programTabAllItemHolder.searchprogramdate = view.FindViewById<TextView>(Resource.Id.searchdate);
                programTabAllItemHolder.searchprogramtime = view.FindViewById<TextView>(Resource.Id.searchtime);
                programTabAllItemHolder.searchProgramTitle = view.FindViewById<TextView>(Resource.Id.searchprogramtitle);
                programTabAllItemHolder.linearsearchdatetime = view.FindViewById<RelativeLayout>(Resource.Id.linearsearchdatetime);
                programTabAllItemHolder.programseparator = view.FindViewById<View>(Resource.Id.programline);
                programTabAllItemHolder.searchprogramresults = view.FindViewById<TextView>(Resource.Id.searchprogramresults);

            }
            else if (GetItemViewType(position) == 1)
            {
                view = LayoutInflater.From(context).Inflate(Resource.Layout.FTSParticipantItemLayout, parent, false);
                programTabAllItemHolder.initialsView = view.FindViewById<TextView>(Resource.Id.searchparticipantinitialsView);
                programTabAllItemHolder.Listimageview = view.FindViewById<ImageView>(Resource.Id.searchparticipantlistimageView);
                programTabAllItemHolder.searchParticipantTitle = view.FindViewById<TextView>(Resource.Id.searchparticipanttitle);
                programTabAllItemHolder.searchparticipantresults = view.FindViewById<TextView>(Resource.Id.searchparticipantresults);
            }
            else if (GetItemViewType(position) == 2)
            {
                view = LayoutInflater.From(context).Inflate(Resource.Layout.FTSInformationItemLayout, parent, false);
                programTabAllItemHolder.searchinformationlistimageView = view.FindViewById<ImageView>(Resource.Id.searchinformationlistimageView);
                programTabAllItemHolder.searchinformationtitle = view.FindViewById<TextView>(Resource.Id.searchinformationtitle);
                programTabAllItemHolder.searchinformationresults = view.FindViewById<TextView>(Resource.Id.searchinformationresults);

            }

            view = LayoutInflater.From(context).Inflate(Resource.Layout.SearchFooterView, parent, false);
            programTabAllItemHolder.searchfooterview = view.FindViewById<LinearLayout>(Resource.Id.ftsfooterview);


            view.Tag = programTabAllItemHolder;
        }
        else
        {
            programTabAllItemHolder = view.Tag as programTabAllItemHolder;
        }

        if (GetItemViewType(position) == 0)
        {
            // setColorsforprogram
            SetViewStyleforProgram(programTabAllItemHolder);
            programTabAllItemHolder.searchProgramTitle.Text = programVTs[position].Title;
            programTabAllItemHolder.searchprogramdate.Text = programVTs[position].StartDate.ToString("dd MMM");
            programTabAllItemHolder.searchprogramtime.Text = programVTs[position].StartDate.ToString("hh:mm tt");
        }


        // participant view
        else if (GetItemViewType(position) == 1)
        {
            programTabAllItemHolder.searchParticipantTitle.Text = programVTs[position].FirstName + programVTs[position].LastName;
            //If profile icon is missing then show initials of First Name and Last Name ahead
            if (string.IsNullOrEmpty(programVTs[position].IconUrl))
            {
                programTabAllItemHolder.Listimageview.Visibility = ViewStates.Gone;
                programTabAllItemHolder.initialsView.Visibility = ViewStates.Visible;
                programTabAllItemHolder.initialsView.Text = Utils.getUserFirstandLastChar(programVTs[position].FirstName, programVTs[position].LastName);
                programTabAllItemHolder.initialsView.SetTextColor(Color.ParseColor(Utils.topNavForegroundColor));

                //Round background image of initials
                GradientDrawable initialsShape = new GradientDrawable();
                initialsShape.SetShape(ShapeType.Oval);
                initialsShape.SetCornerRadius(100f);
                initialsShape.SetColor(Color.ParseColor(Utils.topNavBackgroundColor));
                initialsShape.SetStroke(1, Color.ParseColor(Utils.topNavBackgroundColor));

                //Invert the colors if theme is light
                if (!Util.IsColorDark(Color.ParseColor(Utils.topNavBackgroundColor)))
                {
                    initialsShape.SetColor(Color.ParseColor(Utils.topNavForegroundColor));
                    initialsShape.SetStroke(1, Color.ParseColor(Utils.topNavForegroundColor));
                    programTabAllItemHolder.initialsView.SetTextColor(Color.ParseColor(Utils.topNavBackgroundColor));
                }

                programTabAllItemHolder.initialsView.SetBackgroundDrawable(initialsShape);
            }
            else
            {
                programTabAllItemHolder.initialsView.Visibility = ViewStates.Gone;
                MyApp.picassoWithCache.Load(programVTs[position].IconUrl).Into(programTabAllItemHolder.Listimageview);
            }
            //int check = position + 1;
            //if ( check%3 == 0)
            //{
            //    programTabAllItemHolder.seachparticipantsshowmore.Visibility = ViewStates.Visible;
            //}

        }
        else if (GetItemViewType(position) == 2)
        {
            programTabAllItemHolder.searchinformationtitle.Text = programVTs[position].Title;
            if (string.IsNullOrEmpty(programVTs[position].IconUrl))
            {
                programTabAllItemHolder.searchinformationlistimageView.SetImageResource(Resource.Drawable.linked_info_default_icon);
            }
            else
            {
                MyApp.picassoWithCache.Load(programVTs[position].IconUrl).Into(programTabAllItemHolder.searchinformationlistimageView);
            }

        }



        return view;
    }

【问题讨论】:

    标签: android android-listview android-adapter


    【解决方案1】:

    您可以创建一个自定义视图,将其充气然后可以像这样使用:

    View headerView = getLayoutInflater().inflate(R.layout.listview_header, null);
    listView.addHeaderView(headerView);
    

    更多信息可以查看this link

    【讨论】:

    • 问题是如何添加Section Footer,而不是整个List Header。
    【解决方案2】:

    有很多方法可以实现这一点,但由于您没有为您的适配器和数据结构提供任何代码示例,因此很难给出准确的答案。

    在添加getView 后编辑更新:

    看起来你的数据结构是一个对象数组 您只需要像我在下面所做的那样重写 getItemViewType 方法,以返回当前对象内容的正确类型。

    这可以通过向您的对象添加一个新的成员变量来指示行类型来完成。

    例如programVTs[position].rowType 根据行类型,值为 0 或 1 或 2

    那么你的getItemViewType 可能看起来像:-

    @Override
        public int getItemViewType(int position) {
            return programVTs[position].rowType;
    }
    
    

    我认为你可以从内容中推断出行类型

    下面是getItemViewType的伪代码

    if (programVTs[position].Title and programVTs[position].StartDate are not null or empty)
    return 0;
    
    else if (programVTs[position].FirstName and programVTs[position].LastName are not null or empty)
    return 1;
    
    else return 2;
    

    结束更新

    但是,通常如何添加节标题有一个共同的主题。

    节标题通常作为数据集中的普通列表视图行插入,但是是不同的对象类型或具有附加成员变量来表示它们是标题。

    当适配器的getView 方法处理项目时,它会检查对象类型或成员变量以将该行格式化为普通项目或节标题行。

    此方法也可以轻松扩展为添加页脚,您需要插入一个额外的数据项,该数据项具有导致getView 将其视为页脚的属性。

    一种方法:- 为页眉和页脚行创建一些 Java 对象(普通行只使用字符串对象) 为您的适配器创建一个通用对象列表以进行处理 然后适配器检查对象的类型是否在列表中并进行相应的处理

    
    public class Footer {
    
        public String itemText;
    
        public Footer(String text){
            itemText = text;
        }
    }
    
    public class Header {
    
        public String itemText;
    
        public Header(String text){
            itemText = text;
        }
    }
    
    public class ItemAdapter extends BaseAdapter {
    
        private ArrayList<Object> mData;
        private LayoutInflater mInflater;
    
        private static final int NORMAL_ITEM = 0;
        private static final int HEADER_ITEM = 1;
        private static final int FOOTER_ITEM = 2;
    
        public ItemAdapter(Context context, ArrayList<Object> data){
            mData = data;
            mInflater = (LayoutInflater.from(context));
        }
    
        @Override
        public int getCount(){
            return mData.size();
        }
    
        @Override
        public Object getItem(int position){
            return mData.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public int getViewTypeCount() {
            return 3;
        }
    
        @Override
        public int getItemViewType(int position) {
            Object mObject = getItem(position);
            if (mObject instanceof String){
                return NORMAL_ITEM;
            } else if (mObject instanceof Header) {
                return HEADER_ITEM;
            } else if (mObject instanceof Footer) {
                return FOOTER_ITEM;
            } else {
                return IGNORE_ITEM_VIEW_TYPE;
            }
        }
    
        public View getView(int position, View convertView, ViewGroup parent) {
            int rowType = getItemViewType(position);
            Object object = getItem(position);
    
            View view;
            TextView textView;
    
            // In this simple case all row items are inflated as Textview's to contain the string
            // With the background color changed after inflation
            // But each object could use a different layout for each object type
            // e.g An ImageView, etc
            switch (rowType) {
                case NORMAL_ITEM:
                    view = mInflater.inflate(R.layout.list_item, parent, false);
                    textView = (TextView) view.findViewById(R.id.list_item);
                    textView.setText((String) object);
                    break;
                case HEADER_ITEM:
                    view = mInflater.inflate(R.layout.list_item, parent, false);
                    textView = (TextView) view.findViewById(R.id.list_item);
                    // Set the background to red because it is a Header row
                    textView.setBackgroundColor(Color.RED);
                    // Cast the object from generic list to Header type
                    Header header = (Header) object;
                    textView.setText(header.itemText);
                    break;
                case FOOTER_ITEM:
                    view = mInflater.inflate(R.layout.list_item, parent, false);
                    textView = (TextView) view.findViewById(R.id.list_item);
                    // Set the background to green because it is a Header row
                    textView.setBackgroundColor(Color.GREEN);
                    Footer footer = (Footer) object;
                    textView.setText(footer.itemText);
                    break;
    
                    default:
                        return convertView;
    
            }
    
            return view;
        }
    
    }
    
    public class MainActivity extends AppCompatActivity {
    
        private ItemAdapter mAdapter;
        private ListView listView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // Create the dataset for the Adapter
            ArrayList<Object> mList = new ArrayList<Object>();
            mList.add(new Header("Header 1"));
            mList.add("Item 1");
            mList.add("Item 2");
            mList.add(new Footer("Footer 1"));
            mList.add(new Header("Header 2"));
            mList.add("Item 3");
            mList.add(new Footer("Footer 2"));
    
            // Create Adapter
            mAdapter = new ItemAdapter(this, mList);
    
            listView = (ListView) findViewById(R.id.listView);
            listView.setAdapter(mAdapter);
        }
    }
    
    

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    
    

    list_item.xml

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

    这将产生一个像

    【讨论】:

    • 我已经做到了。我只是根据列表最后一项的类型添加持久性最后一项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 2019-03-14
    • 1970-01-01
    • 2015-02-02
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    相关资源
    最近更新 更多