ListView

  • 一、ListView简单用法
  • 1、新建ListView布局
  • 2、ListView实现
  • 3、效果图
  • 二、定制ListView的界面
  • 1、自定义实体类:
  • 2、自定义布局:
  • 3、自定义适配器:
  • 4、优化ListView运行效率
  • 5、自定义ListView界面实现并设置ListView点击事件:
  • 6、自定义界面效果图


一、ListView简单用法

由于手机屏幕空间都比较有限,能够一次性在屏幕上面显示的内容不多,当我们的程序有大量数据需要展示时,就可以借助ListView来实现。ListView允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,同时屏幕上原有的数据则会滚出屏幕。如查看QQ聊天记录等都是用的这个控件。
用法:

1、新建ListView布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/listview_1"
        android:layout_width="match_parent" //占据整个屏幕
        android:layout_height="match_parent" />

</LinearLayout>

2、ListView实现

数组中的数据不能直接传递给ListView,我们需要通过适配器来完成。ArrayAdapter可以通过泛型来指定要适配的数据类型,ArrayAdapter有多个构造函数的重载,应该根据实际情况去选择。这里将泛型指定为String,然后在ArrayAdapte的构造函数中依次传入当前上下文、ListView子项id以及要适配的数据。注意:使用android.R.layout.simple_list_item_1作为子项布局id,这是一个Android内置的布局文件,里面只有一个TextView,可用于简单的显示一段文本。

public class ListViewActivity extends Activity {

    private String[] data={"Apple","Banana","Orange","Red","Color","blue","yellow",
                           "Apple","Banana","Orange","Red","Color","blue","yellow"};
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_listview);  //设置布局
        ArrayAdapter<String> adapter=new ArrayAdapter<String>(ListViewActivity.this,android.R.layout.simple_list_item_1,data);
        ListView listView=findViewById(R.id.listview_1);
        listView.setAdapter(adapter);
    }
}

3、效果图

android 开发在自定义组合View添加一个View android自定义listview_android

二、定制ListView的界面

1、自定义实体类:

//自定义类MyType 
//name表示名字,imageId表示名字对应的图片的资源id
public class MyType {
    private String name;
    private int imageId;
    public MyType(String name,int imageId){
        this.name=name;
        this.imageId=imageId;
    }
    public String getName()
    {
        return name;
    }
    public  int getImageId()
    {
        return imageId;
    }
}

2、自定义布局:

这里是图片+文字布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/mytype_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/mytype_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp" />
</LinearLayout>

3、自定义适配器:

MyTypeAdapter 重写了父类的一组构造方法,用于将上下文、ListView子项布局的id和数据传递进来。然后又重写了getView()方法,这个方法在每个子项被滑动到屏幕的时候会被调用。在getView()方法中使用getItem()方法获得当前项MyType的实例,然后用LayoutInflater为这个子项加载我们传入的布局。

public class MyTypeAdapter extends ArrayAdapter {
    private int resourceId;
    public MyTypeAdapter(Context context, int textViewResourceId, List<MyType>object)
    {
        super(context,textViewResourceId,object);
        resourceId=textViewResourceId;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        MyType myType= (MyType) getItem(position);    //获取当前项的MyType实例
	    View view= LayoutInflater.from(getContext()).inflate(resourceId,parent,false);//加载布局
	    
	    //获取控件实例
        TextView mytypeName=(TextView) view.findViewById(R.id.mytype_name);
        ImageView mytypeImage=(ImageView)view.findViewById(R.id.mytype_image);
        mytypeImage.setImageResource(myType.getImageId());
        mytypeName.setText(myType.getName());
        return  view;
    }
}

4、优化ListView运行效率

因为getvVew()中,每次都会将布局重新加载一遍,当ListView快速滚动时,就会成为性能瓶颈。
getView()方法中的参数convertView用于将之前加载好的布局进行缓存,以便可以重用。为了避免重复加载控件实例,可以借助一个自定义ViewHolder来对这部分进行优化

public class MyTypeAdapter extends ArrayAdapter {
    private int resourceId;
    public MyTypeAdapter(Context context, int textViewResourceId, List<MyType>object)
    {
        super(context,textViewResourceId,object);
        resourceId=textViewResourceId;
    }

    //创建一个ViewHolder,用于对控件的实例进行缓存,提高性能
    public class ViewHolder
    {
        public ImageView fruitImage;
        public TextView fruitname;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        MyType myType= (MyType) getItem(position);    //获取当前项的MyType实例

        //convertView用于将之前加载好的布局进行缓存,提高性能
        View view;
        ViewHolder  viewHolder;
        if(convertView==null){
            view= LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
            viewHolder=new ViewHolder();
            viewHolder.fruitImage=(ImageView)view.findViewById(R.id.mytype_image);
            viewHolder.fruitname=(TextView) view.findViewById(R.id.mytype_name);
            view.setTag(viewHolder);    //将viewHolder存储在view中
        }
        else{
            view=convertView;
            viewHolder=(ViewHolder)view.getTag(); //重新获取ViewHolder
        }
        
        viewHolder.fruitImage.setImageResource(myType.getImageId());
        viewHolder.fruitname.setText(myType.getName());
        return  view;
    }
}

5、自定义ListView界面实现并设置ListView点击事件:

public class ListViewActivity extends Activity {

    private List<MyType> fruitList=new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_listview);  //设置布局

        //自定义adapter
        initFruits(); //初始化数据
        MyTypeAdapter adapter=new MyTypeAdapter(ListViewActivity.this,R.layout.mytype_item,fruitList);
        ListView listView=(ListView)findViewById(R.id.listview_1);
        listView.setAdapter(adapter);

        /*设置listview点击事件*/
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                MyType fruit=fruitList.get(position);
                Toast.makeText(ListViewActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show();
            }
        });
    }


    private void initFruits(){
        for (int i=0;i<10;i++)
        {
            MyType first=new MyType("星空画具",R.drawable.first);
            fruitList.add(first);
            MyType second=new MyType("星空连体衣",R.drawable.second);
            fruitList.add(second);
            MyType three=new MyType("星空棉花",R.drawable.three);
            fruitList.add(three);
            MyType four=new MyType("星空奶瓶",R.drawable.four);
            fruitList.add(four);
            MyType five=new MyType("星空拼图",R.drawable.five);
            fruitList.add(five);
            MyType six=new MyType("星空温度计",R.drawable.six);
            fruitList.add(six);
        }
    }
}

6、自定义界面效果图

android 开发在自定义组合View添加一个View android自定义listview_android_02