具有多种布局的Android ListView

Posted

技术标签:

【中文标题】具有多种布局的Android ListView【英文标题】:Android ListView with multiple layouts 【发布时间】:2015-06-10 15:00:28 【问题描述】:

我必须显示一个包含不同类型视图的列表。所以我必须用一个适配器定义一个 ListView,我必须在其中膨胀多个视图。我已经通过example 给出,但问题是我的列表不是对称的,就像每次在 4 个项目后重复标题的示例一样。所以我在getView()中面临重复使用项目的问题@

 public View getView(int position, View convertView, ViewGroup parent)    
    int type = getItemViewType(position);
    if (convertView == null) 
        holder = new ViewHolder();
        switch (type) 
             case TYPE_1:
             convertView = mInflater.inflate(R.layout.item1, null);
             .......
             break;

             case TYPE_2:
             convertView = mInflater.inflate(R.layout.item2, null);
             .......
             break;
        
        convertView.setTag(holder);
     else 
        holder = (ViewHolder)convertView.getTag();
    
    ............
    ............

现在如果convertView 不为null,但之前使用的item 类型不同,那么布局将不匹配。这段代码将如何处理这个问题?

【问题讨论】:

不要为 convertview 检查 null 条件,这将始终使项目布局膨胀。 您需要为 item1 和 item2 布局创建 2 个 ViewHolder,并且在 elseconvertView !=null 您需要检查 type 并转换为 ViewHolder1ViewHolder2 。 ..你怎么看? 如果列表视图项具有非对称布局,那么您可以拥有包含所有必需元素的单个列表项 xml,并且在基于类型的 getView 方法中您可以设置可见性显示/隐藏/消失。 假设第一项是类型 1(具有 layout_1),它将在第 8 个元素中重用,即类型 2(具有 layout_2)。现在,如果第一个项目的标签(实际上是 ViewHolder1 的对象)将其转换为 ViewHolder2,它会起作用吗?此外,布局也会有所不同。它将如何运作? 【参考方案1】:

您可以查看此示例适配器。 getViewTypeCount 方法返回您的不同类型行。 getItemViewType 方法,如果位置等于 0,则膨胀第一行布局,否则膨胀其他行布局。您可以自定义此代码示例。

    import java.util.List;
    import android.app.Activity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;

    /**
     * Created by MustafaS on 9.2.2015.
     */
    public class CustomArrayAdapter extends ArrayAdapter<YourModel> 

       @Override
       public int getItemViewType(int position) 

          if (position == 0) 
             return 0;
          
          else 
             return 1;
          
       

       @Override
       public int getViewTypeCount() 
          return 2;
       

       @Override
       public View getView(int position, View convertView, ViewGroup parent) 
          int type = getItemViewType(position);
          if (type == 0) 
             if (convertView == null) 
                convertView = LayoutInflater.from(activity).inflate(R.layout.listview_first_row, parent, false);
                viewHolderFirst = new ViewHolderFirst();
                convertView.setTag(viewHolderFirst);
             
             else 
                viewHolderFirst = (ViewHolderFirst) convertView.getTag();
             

          
          else 
             if (convertView == null) 
                convertView = LayoutInflater.from(activity).inflate(R.layout.listview_other_row, parent, false);
                viewHolder = new ViewHolder();

             
             else 
                viewHolder = (ViewHolder) convertView.getTag();
             
          
          return convertView;
       

       protected class ViewHolderFirst 
          private RunnableViewPager pager;
          private CircleIndicator   indicator;
       

       protected class ViewHolder 
          private ImageView imageviewRestaurant;
          private TextView  textviewRestaurantName;
          private TextView  textviewType;
          private TextView  textviewPrice;
          private TextView  textviewDistance;
          private ImageView imageviewCall;
          private ImageView imageviewCalendar;
       
    

【讨论】:

假设第一项是类型 1(具有 layout_1),它将在第 8 个元素中重用,即类型 2(具有 layout_2)。现在,如果第一个项目的标签(实际上是 ViewHolderFirst 的对象)将其转换为 ViewHolder,它会起作用吗?此外,布局也会有所不同。它将如何运作? 如果你的第一行有很多不同的其他行,你应该这样。但是如果你的行相似,你可以一排xml和一个viewholder layout_1 和 layout_2 不同。如何将它用于之前使用类型 1 的类型 2?【参考方案2】:

您可以通过覆盖方法 getViewCount()getItemViewType(int position) 来做到这一点

首先,您只需返回您拥有的不同视图的数量。

在第二个中,您为每个不同的视图返回一个唯一标识符。

在您的getView() 方法中,您检查视图类型并为其添加正确的布局。

有关该主题的更多信息:Android ListView with different layouts for each row

Android ListView with different layouts for each row

【讨论】:

【参考方案3】:

这是您在 ListView 或 RecyclerView 中使用不同类型的视图时需要使用的:-

getItemViewType() and getViewTypeCount()

首先,您需要使用 getViewTypeCount() 并返回列表中所需的唯一视图数。然后覆盖 getItemViewType() 并根据您希望视图在 ListView 内更改的任何条件返回视图类型。

希望它会有所帮助。

【讨论】:

以上是关于具有多种布局的Android ListView的主要内容,如果未能解决你的问题,请参考以下文章

具有多种布局的 React Router v4

Android入门——构建UI布局的多种方式

Android自定义FlowLayout,支持多种布局优化--android-flowlayout

Android自定义FlowLayout,支持多种布局优化--android-flowlayout

Android进阶——构建UI布局的多种方式总结

android-多种方式实现主界面的Tab