Android学习笔记12—自定义 ListView开发详解(二)

引言

该节介绍如何在开发中使用ViewHolder实现自定义ListView

开发流程

Step-1 新建一个Module,命名为ViewHolderListViewActivity
Step-2 在ViewHolderListViewActivity绑定的布局文件中添加ListView组件



Step-3 添加自定义布局文件设置每个Item的基本样式










    

    

    










    

    

    






Step-4 新建一个ViewHolder文件,用于声明获取各组件的id的变量

public class InfoViewHolder {
    public ImageView imgIcon, btnPin;
    public TextView txtUserName, txtInfo, txtPublish;
    public LinearLayout layoutImages, layoutReplys;
}

Step-5 自定义适配器

public class InfoAdapter extends BaseAdapter {

private Context mContext;
private List> listItems;
private LayoutInflater inflater;

public InfoAdapter(List> listItems, Context mContext) {
    super();
    this.inflater = LayoutInflater.from(mContext);
    this.listItems = listItems;
    this.mContext = mContext;
}

@Override
public int getCount() {
    return this.listItems.size();
}

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

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

/*
* 使用循环迭代遍历listItems中的每一个选项对象,并通过转换视图对象ConverView动态加载当前选项布局资源
* 同时根据ListItem中的选项对象参数,动态设置其组件显示和内容
* */
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    /* 步骤1:创建一个空的InfoViewHolder对象 */
    InfoViewHolder infoViewHolder = null;
    /* 步骤2:判断但钱的转换视图参数convertView是否为空,若为空则实例化viewHolder对象中的组件 */
    if(convertView == null){
        infoViewHolder = new InfoViewHolder();
        /* 步骤3:转换视图绑定列表选项布局文件 */
        convertView = this.inflater.inflate(R.layout.listitem_view_holder_list_view, null);
        /* 步骤4:获取列表布局中的所有组件对象 */
        infoViewHolder.imgIcon = (ImageView) convertView.findViewById(R.id.imgIcon);
        infoViewHolder.txtUserName = (TextView) convertView.findViewById(R.id.txtUserName);
        infoViewHolder.txtInfo = (TextView) convertView.findViewById(R.id.txtInfo);
        infoViewHolder.layoutImages = (LinearLayout) convertView.findViewById(R.id.layoutImages);
        infoViewHolder.txtPublish = (TextView) convertView.findViewById(R.id.txtPublish);
        infoViewHolder.btnPin = (ImageView) convertView.findViewById(R.id.btnPin);
        infoViewHolder.layoutReplys = (LinearLayout) convertView.findViewById(R.id.layoutReplys);

        /* 步骤5:转换视图设置ViewHolder对象*/
        convertView.setTag(infoViewHolder);
    }else{
        infoViewHolder = (InfoViewHolder) convertView.getTag();
    }

    /* 步骤6:动态为每一个选项对象赋值 */
    infoViewHolder.imgIcon.setImageResource((Integer) this.listItems.get(position).get("imgIcon"));
    infoViewHolder.txtUserName.setText(this.listItems.get(position).get("txtUserName").toString());
    infoViewHolder.txtInfo.setText(this.listItems.get(position).get("txtInfo").toString());
    infoViewHolder.txtPublish.setText(this.listItems.get(position).get("txtPublish").toString());

    /* 步骤7:动态设置适配器中的组件显示 */
    if(this.listItems.get(position).get("layoutImages").toString().equals("0")){
        infoViewHolder.layoutImages.setVisibility(View.GONE);
    }

    if(this.listItems.get(position).get("layoutReplys").toString().equals("0")){
        infoViewHolder.layoutReplys.setVisibility(View.GONE);
    }

    /* 步骤8:监听器绑定 */
    infoViewHolder.btnPin.setOnClickListener(new ViewOcl(position));

    return convertView;
}

/* 自定义一个单击监听器 */
private class ViewOcl implements View.OnClickListener{
    private int position;

    public ViewOcl(int position) {
        this.position = position;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btnPin:
                Toast.makeText(mContext, "你要回复 ["+ listItems.get(position).get("txtUserName") +"]", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

}
Step-6 在Activity中初始化ListView适配器并绑定

public class ViewHolderListViewActivity extends AppCompatActivity {

private ListView listViewInfo;
private List> listItems;

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

    this.listItems = this.getListItems();

    InfoAdapter adapter = new InfoAdapter(this.listItems, this);

    this.listViewInfo = (ListView) findViewById(R.id.listViewInfo);

    this.listViewInfo.setAdapter(adapter);
}

private List> getListItems() {
    List> listItems = new ArrayList<>();

    Map item01 = new HashMap<>();
    item01.put("id", 1);
    item01.put("imgIcon", R.drawable.photo01);
    item01.put("txtUserName", "西施");
    item01.put("txtInfo", "西施发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息");
    item01.put("txtPublish", new SimpleDateFormat("yyyy-MM-dd  hh:mm:ss").format(new Date()));
    item01.put("layoutImages", "0");
    item01.put("layoutReplys", "1");

    listItems.add(item01);

    Map item02 = new HashMap<>();
    item02.put("id", 2);
    item02.put("imgIcon", R.drawable.photo02);
    item02.put("txtUserName", "貂蝉");
    item02.put("txtInfo", "貂蝉发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息");
    item02.put("txtPublish", new SimpleDateFormat("yyyy-MM-dd  hh:mm:ss").format(new Date()));
    item02.put("layoutImages", "1");
    item02.put("layoutReplys", "0");

    listItems.add(item02);

    Map item03 = new HashMap<>();
    item03.put("id", 3);
    item03.put("imgIcon", R.drawable.photo03);
    item03.put("txtUserName", "吕布");
    item03.put("txtInfo", "吕布发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息");
    item03.put("txtPublish", new SimpleDateFormat("yyyy-MM-dd  hh:mm:ss").format(new Date()));
    item03.put("layoutImages", "1");
    item03.put("layoutReplys", "1");

    listItems.add(item03);

    return listItems;
  }
}
结果展示

Android学习笔记12—自定义 ListView开发详解(二)_第1张图片
ViewHolderListView.png
代码清单

activity_view_holder_list_view.xml





    

listitem_view_holder_list_view.xml













    

    

    










    

    

    



InfoViewHolder.java

package com.chinasofti.holder;

import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class InfoViewHolder {
    public ImageView imgIcon, btnPin;
    public TextView txtUserName, txtInfo, txtPublish;
    public LinearLayout layoutImages, layoutReplys;
}

InfoAdapter.java

package com.chinasofti.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.chinasofti.demo04listview.R;
import com.chinasofti.holder.InfoViewHolder;

import java.util.List;
import java.util.Map;

public class InfoAdapter extends BaseAdapter {

private Context mContext;
private List> listItems;
private LayoutInflater inflater;

public InfoAdapter(List> listItems, Context mContext) {
    super();
    this.inflater = LayoutInflater.from(mContext);
    this.listItems = listItems;
    this.mContext = mContext;
}

@Override
public int getCount() {
    return this.listItems.size();
}

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

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

/*
* 使用循环迭代遍历listItems中的每一个选项对象,并通过转换视图对象ConverView动态加载当前选项布局资源
* 同时根据ListItem中的选项对象参数,动态设置其组件显示和内容
* */
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // 步骤1:创建一个空的InfoViewHolder对象
    InfoViewHolder infoViewHolder = null;
    // 步骤2:判断但钱的转换视图参数convertView是否为空,若为空则实例化viewHolder对象中的组件
    if(convertView == null){
        infoViewHolder = new InfoViewHolder();
        // 步骤3:转换视图绑定列表选项布局文件
        convertView = this.inflater.inflate(R.layout.listitem_view_holder_list_view, null);
        // 步骤4:获取列表布局中的所有组件对象
        infoViewHolder.imgIcon = (ImageView) convertView.findViewById(R.id.imgIcon);
        infoViewHolder.txtUserName = (TextView) convertView.findViewById(R.id.txtUserName);
        infoViewHolder.txtInfo = (TextView) convertView.findViewById(R.id.txtInfo);
        infoViewHolder.layoutImages = (LinearLayout) convertView.findViewById(R.id.layoutImages);
        infoViewHolder.txtPublish = (TextView) convertView.findViewById(R.id.txtPublish);
        infoViewHolder.btnPin = (ImageView) convertView.findViewById(R.id.btnPin);
        infoViewHolder.layoutReplys = (LinearLayout) convertView.findViewById(R.id.layoutReplys);

        // 步骤5:转换视图设置ViewHolder对象
        convertView.setTag(infoViewHolder);
    }else{
        infoViewHolder = (InfoViewHolder) convertView.getTag();
    }

    // 步骤6:动态为每一个选项对象赋值
    infoViewHolder.imgIcon.setImageResource((Integer) this.listItems.get(position).get("imgIcon"));
    infoViewHolder.txtUserName.setText(this.listItems.get(position).get("txtUserName").toString());
    infoViewHolder.txtInfo.setText(this.listItems.get(position).get("txtInfo").toString());
    infoViewHolder.txtPublish.setText(this.listItems.get(position).get("txtPublish").toString());

    // 步骤9:动态设置适配器中的组件显示
    if(this.listItems.get(position).get("layoutImages").toString().equals("0")){
        infoViewHolder.layoutImages.setVisibility(View.GONE);
    }

    if(this.listItems.get(position).get("layoutReplys").toString().equals("0")){
        infoViewHolder.layoutReplys.setVisibility(View.GONE);
    }

    // 步骤10:监听器绑定
    infoViewHolder.btnPin.setOnClickListener(new ViewOcl(position));

    return convertView;
}

// 自定义一个单击监听器
private class ViewOcl implements View.OnClickListener{
    private int position;

    public ViewOcl(int position) {
        this.position = position;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btnPin:
                Toast.makeText(mContext, "你要回复 ["+ listItems.get(position).get("txtUserName") +"]", Toast.LENGTH_SHORT).show();
                break;
        }
      }
   }
}

ViewHolderListViewActivity.java

package com.chinasofti.demo04listview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;

import com.chinasofti.adapter.InfoAdapter;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ViewHolderListViewActivity extends AppCompatActivity {

private ListView listViewInfo;
private List> listItems;

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

    this.listItems = this.getListItems();

    InfoAdapter adapter = new InfoAdapter(this.listItems, this);

    this.listViewInfo = (ListView) findViewById(R.id.listViewInfo);

    this.listViewInfo.setAdapter(adapter);
}

private List> getListItems() {
    List> listItems = new ArrayList<>();

    Map item01 = new HashMap<>();
    item01.put("id", 1);
    item01.put("imgIcon", R.drawable.photo01);
    item01.put("txtUserName", "西施");
    item01.put("txtInfo", "西施发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息");
    item01.put("txtPublish", new SimpleDateFormat("yyyy-MM-dd  hh:mm:ss").format(new Date()));
    item01.put("layoutImages", "0");
    item01.put("layoutReplys", "1");

    listItems.add(item01);

    Map item02 = new HashMap<>();
    item02.put("id", 2);
    item02.put("imgIcon", R.drawable.photo02);
    item02.put("txtUserName", "貂蝉");
    item02.put("txtInfo", "貂蝉发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息");
    item02.put("txtPublish", new SimpleDateFormat("yyyy-MM-dd  hh:mm:ss").format(new Date()));
    item02.put("layoutImages", "1");
    item02.put("layoutReplys", "0");

    listItems.add(item02);

    Map item03 = new HashMap<>();
    item03.put("id", 3);
    item03.put("imgIcon", R.drawable.photo03);
    item03.put("txtUserName", "吕布");
    item03.put("txtInfo", "吕布发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息发送的消息");
    item03.put("txtPublish", new SimpleDateFormat("yyyy-MM-dd  hh:mm:ss").format(new Date()));
    item03.put("layoutImages", "1");
    item03.put("layoutReplys", "1");

    listItems.add(item03);

    return listItems;
  }
}

你可能感兴趣的:(Android学习笔记12—自定义 ListView开发详解(二))