Android ListView 多种布局--进阶二

Android ListView 多种布局–进阶一 中提及了这么一个需求,本博文就这个需求的实现做进一步探讨。

前面是单列,后面是双列的情况,使用ListView实现,一般的解决思路是处理getView和getCount方法,如下实现:

  • 首先实现Adapter,处理getView和getCount方法
public class DoubleAdapter extends BaseAdapter implements OnClickListener{
    private List<String> mDataList = new ArrayList<String>();
    private Context mContext;

    private final static int PRESIZE = 5;

    public DoubleAdapter(Context context,List<String> datas){
        this.mContext = context;
        this.mDataList = datas;
    }
    @Override
    public int getCount() {
        return PRESIZE + (mDataList.size()- PRESIZE) % 2 == 0 ? (mDataList.size()- PRESIZE) / 2 : (mDataList.size()- PRESIZE) / 2 + 1;
    }
    @Override
    public Object getItem(int position) {
        return null;
    }
    @Override
    public long getItemId(int position) {
        return position;
    }
    @SuppressLint("InflateParams")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHodler hodler = null;
        if(convertView == null){
            hodler = new ViewHodler();
            LayoutInflater inflater = LayoutInflater.from(mContext);
            convertView = inflater.inflate(R.layout.item, null);
            hodler.textView1 = (TextView) convertView.findViewById(R.id.text1);
            hodler.textView2 = (TextView) convertView.findViewById(R.id.text2);
            hodler.layout1 = (LinearLayout) convertView.findViewById(R.id.item_layout1);
            hodler.layout2 = (LinearLayout) convertView.findViewById(R.id.item_layout2);

            convertView.setTag(hodler);
        }else{
            hodler = (ViewHodler) convertView.getTag();
        }

        if (position >= PRESIZE ) {

            String item1 = "";
            String item2 = "";

            if(position * 2 + 1< mDataList.size()){
                item1 = mDataList.get(position * 2 - PRESIZE);
                item2 = mDataList.get(position * 2 + 1 - PRESIZE);
            }else if(position * 2 + 1== mDataList.size()){
                item1 = mDataList.get(position * 2 - PRESIZE);
                item2 = "";
            }

            if(item1 != null){
                hodler.textView1.setText(item1);
                hodler.layout1.setOnClickListener(this);
                hodler.layout1.setTag(item1);
            }

            if(item2 != null){
                hodler.textView2.setText(item2);
                hodler.layout2.setOnClickListener(this);
                hodler.layout2.setTag(item2);
            }
        }else {
            String item = mDataList.get(position);
            hodler.textView1.setText(item);
            hodler.layout1.setOnClickListener(this);
            hodler.layout1.setTag(item);

            hodler.textView2.setText("");
            hodler.layout2.setOnClickListener(this);
            hodler.layout2.setTag("");
        }

        return convertView;
    }

    class ViewHodler {
        TextView textView1;
        TextView textView2;
        LinearLayout layout1;
        LinearLayout layout2;
    }
    @Override
    public void onClick(View v) {
        Toast.makeText(mContext, v.getTag().toString(), Toast.LENGTH_SHORT).show();
    }
}
  • 接着是Activity将数据绑定View
public class DoubleListViewActivity extends Activity {
    private List<String> datas;
    private ListView listView;
    private DoubleAdapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        getData();
        initView();
    }

    private void initView(){
        listView = (ListView) findViewById(R.id.listView);
        adapter = new DoubleAdapter(this, datas);
        listView.setAdapter(adapter);
    }

    private void getData(){
        datas = new ArrayList<String>();
        for(int i = 0;i < 60;i++){
            datas.add("NO:"+i);
        }
    }
}

我们来看看关键的实现点:

@Override
public int getCount() {
    return PRESIZE + (mDataList.size()- PRESIZE) % 2 == 0 ? (mDataList.size()- PRESIZE) / 2 : (mDataList.size()- PRESIZE) / 2 + 1;
}

@SuppressLint("InflateParams")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHodler hodler = null;

    if(position * 2 + 1< mDataList.size()){
        item1 = mDataList.get(position * 2 - PRESIZE);
        item2 = mDataList.get(position * 2 + 1 - PRESIZE);
    }else if(position * 2 + 1== mDataList.size()){
        item1 = mDataList.get(position * 2 - PRESIZE);
        item2 = "";
    }
}

小结一下上面的实现思路: 主要是重新计算getCount,不满足偶数的补充一个, 重新绑定数据,每行绑定两个数据,然后一个Holder初始化对应的itemView,再更新到view上去。

上面的实现思路只能说很一般,比较麻烦的是计算getCount和getView的处理,有木有更好的方式处理一行两列的ListView思路呢?

当然有的,其实很简单,就是从数据端入手,而不是像上面那样从绑定到View处着手,那么从数据端该如何着手呢,其实就是将原有的数据封装一下,每两个bean封装成一个bean,接下来绑定过程和普通的Adapter一样,这样说是不是问题就迎刃而解了,简单看一下实现吧

  • 首先将数据封装一下
public static final class BrandRecommedProduct {
    private ProductBean productLeft;
    private ProductBean productRight;
    public BrandRecommedProduct() {
    }
    public BrandRecommedProduct(ProductBean productLeft, ProductBean productRight) {
        this.productLeft = productLeft;
        this.productRight = productRight;
    }
    public ProductBean getProductLeft() {
        return productLeft;
    }
    public void setProductLeft(ProductBean productLeft) {
        this.productLeft = productLeft;
    }
    public ProductBean getProductRight() {
        return productRight;
    }
    public void setProductRight(ProductBean productRight) {
        this.productRight = productRight;
    }
}
  • 接着初始化List数据(将奇数数据去掉最后一个保持始终偶数个数据)
private void updateRecommendProducts(List<ProductBean> recommendProducts) {
    int size = 0;
    if (recommendProducts != null && (size = recommendProducts.size()) > 0) {
        mDataList.add(BrandDetailAdapter.RECOMMEND_PRODUCT_TITLE);
        mRecommendProductSize = size % 2 == 0 ? size : size -1;

        for (int i = 0; i < size; i++) {
            if (size % 2 == 0) {
                BrandRecommedProduct product = new BrandRecommedProduct();
                product.setProductLeft(recommendProducts.get(i));
                i++;
                product.setProductRight(recommendProducts.get(i));
                mDataList.add(product);
            }else {
                if (i == size -1 ) {
                    break;
                }

                BrandRecommedProduct product = new BrandRecommedProduct();
                product.setProductLeft(recommendProducts.get(i));
                i++;
                product.setProductRight(recommendProducts.get(i));
                mDataList.add(product);
            }
        }

        if(mBrandDetailBean.getCat() != null){
            mDataList.add(mBrandDetailBean.getCat());
        }

        mAdapter.notifyDataChanged(mDataList);
    }
} 

这样就可以在初始化数据的时候就包装了两个对等的数据,这样在通过Adapter绑定View的时候就和普通ListView处理相同了。这么做对于简单的View体现不出来很大的优势,如果是复杂的ListView布局就很能体现优势了.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-07 21:16:59

Android ListView 多种布局--进阶二的相关文章

Android——ListView多布局+适配器(二)

Android--ListView多布局+适配器(二) <span style="font-size:18px;">package com.example.administrator.newstop.entity; /** * Created by Administrator on 2016/8/4. */ public class News { private String title; private String pubDate; private int img; p

从零开始学android&lt;ListView数据列表显示组件.二十一.&gt;

与滚动视图(ScrollView)类似的还有一种列表组件(ListView),可以将多个组件加入到ListView之中以达到组件的滚动显示效果,ListView组件本身也有对应的ListView类支持,可以通过操作ListView类以完成对此组组件的操作,ListView类的继承结构如下所示: java.lang.Object ? android.view.View ? android.view.ViewGroup ? android.widget.AdapterView<T extends a

Android ListView Animation 布局动画

AnimationSet set = new AnimationSet(false); Animation animation = new AlphaAnimation(0,1); //AlphaAnimation 控制渐变透明的动画效果 animation.setDuration(500); //动画时间毫秒数 set.addAnimation(animation); //加入动画集合 animation = new TranslateAnimation(1, 13, 10, 50); //S

Android ListView 常用用法(二)

ListView是一个经常用到的控件,ListView里面的每个子项Item可以使一个字符串,也可以是一个组合控件.先说说ListView的实现: 1.准备ListView要显示的数据: 2.使用一维或多维动态数组保存数据: 2.构建适配器,简单地来说,适配器就是Item数组,动态数组有多少元素就生成多少个Item: 3.把适配器添加到ListView,并显示出来. 接下来,就开始UI的XML代码: main.xml代码如下: <?xml version="1.0" encodi

Android ListView多布局讲解

Listview优化是一个老生常谈的事情了,其优化的方面也有很多种,例如,布局重用.在getView()中减少逻辑计算.减少在页面滑动的时候加在图片,而是在页面停止滚动的时候再加在图片.而今天要介绍的是另一种方式,那就是多布局. 一般使用的场景有一下两种情况: ① 当一个item有多重布局的情况下,使用部分隐藏来实现既笨拙又效率低下,这时多布局会是个不错的选择: ② 当一个item很复杂,页面内容多,item高度很高,甚至超过手机屏幕,这个时候就需要使用多布局将页面拆分成多个小item来提高执行

Android学习笔记二十五之ListView多布局实现

Android学习笔记二十五之ListView多布局实现 这一节是介绍ListView这个控件的最后一节,实现一个Item的多布局.像我们经常在用的各种即时通讯工具,QQ.微信等,假设他们的会话界面是ListView实现的,那么ListView就有多种Item布局,这一节,我们就来实现一个ListView的多种Item. 要实现ListView里面有多种Item,就要重写适配器的两个方法getViewTypeCount()和getItemViewType(int position),第一个方法是

Android开发之ListView添加多种布局效果演示

在这个案例中展示的新闻列表,使用到ListView控件,然后在适配器中添加多种布局效果,这里通过重写BaseAdapter类中的 getViewType()和getItemViewType()来做判断,指定ListView列表中指定位置的item加载对应的布局,在 getView中返回对应的视图,之前由于不清楚getViewTypeCount()和getItemViewType()方法,使用得比较少,一直以 为需要添加多个适配器,现在看来当时的想法说明自己见识还不够,哈哈. 第一步:创建放置Li

Android ListView Adapter的getItemViewType和getViewTypeCount多种布局

 <Android ListView Adapter的getItemViewType和getViewTypeCount多种布局> 在Android的ListView中,如果在一个ListView中要实现多种样式的ListView布局样式,则需要在ListView的适配器Adapter中用到:getItemViewType()和getViewTypeCount().getViewTypeCount()告诉ListView需要加载多少种类型的Item View,getItemViewType(

android 实现listview的adapter多种布局方式

这两天在实现某模块的排行榜功能,看了UI给的效果图和切图,感觉有点郁闷,因为平时使用listview时,子项都是只有一种布局方式,而这次却有两种.于是专门研究了下,发现重写adapter的getItemViewType()和getViewTypeCount()方法就可以实现多种布局方式,把自己的实现贴出来共享下. 步骤: 1. 重写 getViewTypeCount() – 返回你有多少个不同的布局: 2. 重写 getItemViewType(int) – 由position返回view ty