ListView加载不同的布局

我们平常使用ListView多半都是用来展示数据的,且每个item的模式都是一样的。但是还有更多的时候会出现不一样的布局,比如你手机联系人的方式。好了不多说,看效果图吧!
在这里插入图片描述
为什么我会想到写这篇文章,事情的起因是我在项目中遇到一个需求。需要实现一个WiFi列表界面,熟悉手机的盆友应该知道WiFi列表不是我们随便写一个ListVIew就能实现的了。开始我的想法是用线性布局,中间夹杂需要的标题栏布局等,可是我操作了大半天,发现一个很致命的问题,已经连接过的WiFi是不会出现在周围热点的列表里面的。(因为项目的WiFi列表实现了自动刷新)如果按照这种思路走下去,在每次刷新之后都要一个一个对照,然后将已经连接的从列表里面移除。很显然这个效率太低了,于是就问同事,同事就告诉我说用一个列表啊。嗯!确实很感谢他。

后来我又开始了不断寻找的道路。在找了很多资料以后终于找到了答案(可能是我自身能力不足,有的东西真的看不明白吧)。关键在于Adapter里面的两个方法。

 @Override
    public int getViewTypeCount() {
        return 2;
    }
    这个方法就是返回你需要展示不同的类型数量,我的项目就两个,所以返回2.
 @Override
    public int getItemViewType(int position) {
        if (types == 0){
            if (position == 3){
                return 0;
            }else {
                return 1;
            }
        }else {
            return position % 2;
        }
    }
    这个是根据位置返回你需要展示的类型,待会我们就会用到。比如说返回0说明我想用1号布局,
    返回1说明我想用2号布局。特别注意一点的这里返回的值必须从0开始,
    且不能大于你返回的类型总数(就是上一个方法返回的数值,原理是看到大神这么说的<(* ̄▽ ̄*)/)
    当然你可以在这里加上自己的逻辑判断哪个位置返回什么,我这里只是简单的显示2个布局。

好来看适配器代码

public class ListAdapter extends BaseAdapter {
    private List<String> contents;
    private LayoutInflater inflater;
    //模拟判断效果,你可以改成其他的值,当然在getItemViewType里面的值也要变一下
    private int types = 1;
    
    public ListAdapter(List<String> contents, Context context) {
        this.contents = contents;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return contents == null ? 0 :contents.size();
    }

    @Override
    public Object getItem(int position) {
        return contents.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        int type = getItemViewType(position);
        if (view == null) {
            switch (type) {
                case 0:
                    view = inflater.inflate(R.layout.item_right, parent, false);
                    break;
                case 1:
                    view = inflater.inflate(R.layout.item_left, parent, false);
                    break;
            }
        }
        ViewHolder holder = (ViewHolder) view.getTag();
        if (holder == null) {
            holder = new ViewHolder();
            holder.imageView = (ImageView) view.findViewById(R.id.image);
            holder.textView = (TextView) view.findViewById(R.id.text_content);
        }
        holder.textView.setText(contents.get(position));
        return view;
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        if (types == 0){
            if (position == 3){
                return 0;
            }else {
                return 1;
            }
        }else {
            return position % 2;
        }
    }

    static class ViewHolder {
        TextView textView;
        ImageView imageView;
    }
}

注意这个方法

 public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        int type = getItemViewType(position);
        if (view == null) {
            switch (type) {
                case 0:
                    view = inflater.inflate(R.layout.item_right, parent, false);
                    break;
                case 1:
                    view = inflater.inflate(R.layout.item_left, parent, false);
                    break;
            }
        }
        ViewHolder holder = (ViewHolder) view.getTag();
        if (holder == null) {
            holder = new ViewHolder();
            holder.imageView = (ImageView) view.findViewById(R.id.image);
            holder.textView = (TextView) view.findViewById(R.id.text_content);
        }
        holder.textView.setText(contents.get(position));
        return view;
    }

这里我们根据在getItemViewType里面返回的值进行判断选择不同的布局展示。
布局代码(如果你实现不了这种布局的话我也没办法帮你了骚年)我就不贴了。最后贴上MainActivity代码

public class MainActivity extends AppCompatActivity {
    private ListView listView;
    private List<String> contents;
    private ListAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.list_content);
        contents = new ArrayList<>();
        for (int i = 1;i < 50;i++){
            contents.add("这是第 " + i + "条item");
        }

        adapter = new ListAdapter(contents,this);
        listView.setAdapter(adapter);
    }

}

怎么样,还是比较简单的吧,问题还没有结束哦。如果你设置了点击监听事件你会发现每个item都是会响应点击事件的。如果我想让第四个不能响应点击事件怎么办?这个你可以再Adapter里面重写这个方法

 @Override
    public boolean isEnabled(int position) {
        return super.isEnabled(position);
    }

这个你同样根据位置来判断就好比如说我想让第四个不能点击那就可以写成这样

 public boolean isEnabled(int position) {
        if (position == 4){
        //返回false表示不可以点击
            return false;
        }else {
        //返回true表示可以点击
            return true;
        }
    }

好了,到此,已经实现了不同布局的加载以及某个item不可点击。正所谓好事多磨,仅仅靠这个是不可能做出很好的内容的,加油吧各位!自己也要加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值