android之ListView,GirdView和常用适配器

一:ArrayAdapter

首先是ArrayAdapter,使用ListView做模板吧:

先是布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ArrayAdapterTest">
    <ListView
        android:id="@+id/list_view_array"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ListView>
</LinearLayout>

这没什么好说的了,嘿嘿!

然后是ListView的item的布局,暂时命名为girl_item吧:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:ignore="UseCompoundDrawables">

    <ImageView
        android:id="@+id/item_img"
        android:layout_width="50dp"
        android:layout_height="50dp"
        tools:ignore="ContentDescription" />
    <TextView
        android:id="@+id/item_text"
        android:layout_width="match_parent"
        android:layout_height="50dp" />
</LinearLayout>

在写一个常量类吧,给List提供数据,而且接下来的BaseArray也要用:

public class ConstGirls {
    public static final String girlsName[]={"桃谷绘里香",
            "上原亚衣","早乙女露依","麻生希","水菜丽"};
    public static final int imgIds[]={
        R.drawable.p0,R.drawable.p1,R.drawable.p2,R.drawable.p3,R.drawable.p4};//在drawable分别导入各位的照片,命名为p0,...p4
}

因为这是深夜写的,所以就不找那么多美女了,省得有什么误会!

好吧,再添加一个Girl类:

public class Girl {
    private String name;
    private int id;
    public Girl(String name, int id){
        this.name=name;
        this.id=id;
    }
    public String getName(){return name;}
    public int getId(){return id;}
}

其中name为item的TextView提供内容,id嘛就是ImageView的图片源

接下来的两个类就有点东西了:

继承ArrayAdapter的类:

public class MyArrayAdapter extends ArrayAdapter {
    private int resourceId;

    public MyArrayAdapter(@NonNull Context context, int resource, @NonNull List objects) {
        super(context, resource, objects);
        this.resourceId=resource;
    }

    @NonNull
    @Override
    /*
     *convertView:将之前加载好的布局进行缓存
     */
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        Girl girl= (Girl) getItem(position);
//        注释掉的是未进行优化的
//        View view= null;
//        view=LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
//        ImageView imageView=view.findViewById(R.id.item_img);
//        TextView textView=view.findViewById(R.id.item_text);
//        assert girl != null;
//        imageView.setImageResource(girl.getId());
//        textView.setText(girl.getName());
//        return view;
        View view;
        ViewHolder viewHolder;
        if(convertView==null){
            view=LayoutInflater.from(getContext()).inflate(resourceId,parent,false);//false表示不会为这个View添加父布局(有了父布局就不能添加到ListView中了)
            viewHolder=new ViewHolder();
            viewHolder.imageView=view.findViewById(R.id.item_img);
            viewHolder.textView=view.findViewById(R.id.item_text);
            view.setTag(viewHolder);
        }else{//使用之前加载好的布局
            view=convertView;
            viewHolder=(ViewHolder)view.getTag();
        }
        assert girl != null;
        viewHolder.imageView.setImageResource(girl.getId());
        viewHolder.textView.setText(girl.getName());
        return view;
    }
    class ViewHolder{
        ImageView imageView;
        TextView textView;
    }
}

看如何优化的:

如注释所知:convertView是先前加载好的布局,不为null的时候可以直接使用,这样就不会重复加载布局了;

另外引用ViewHolder这个类作为item控件的载体,类似于RecyclerView中的 onCreateViewHolder,这样就没必要重复使用findViewById来获取控件了!具体优化不再详述,对不住了

好吧,接下来就是就是测试了:

public class ArrayAdapterTest extends AppCompatActivity {

    private List<Girl> girlList=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_array_adapter_test);
        setGirlList();

        ListView myListView=findViewById(R.id.list_view_array);
        MyArrayAdapter adapter=new MyArrayAdapter(this,R.layout.girl_item,girlList);
        myListView.setAdapter(adapter);

    }
    private void setGirlList(){
        for(int m=0;m<3;m++){
            for(int i = 0; i< ConstGirls.girlsName.length; i++){
                Girl girl=new Girl(ConstGirls.girlsName[i],ConstGirls.imgIds[i]);
                girlList.add(girl);
            }
        }
    }
}

诡异的是setGirlList中为什么先循环三次:因为就五个美女,没有滑动的效果,所以循环增加了三次,这样就填满屏幕了呀!

k


显示是顺利显示出来了,添加点击事件,在mListView.setAdapter(adapter)下面添加如下代码:

 myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Girl girl=girlList.get(i);
                Toast.makeText(ArrayAdapterTest.this,"你点击了 "+girl.getName()+" 开不开心",Toast.LENGTH_SHORT).show();
            }
        });

二:BaseAdapter

这里BaseAdapter也用ListView做例子:

Layout文件和ArrayAdapter没有差别,毕竟同样是引用ListView,直接看自定义的适配器吧

public class MyBaseAdapter extends BaseAdapter {
    private List<Girl> girlList;
    private LayoutInflater inflater;
    private int resourceId;//girl_item的id

    public MyBaseAdapter(Context context, List<Girl> list, int resourceId){
        this.girlList=list;
        this.resourceId=resourceId;
        inflater=LayoutInflater.from(context);
    }
    @Override
    public int getCount() {//数据的个数
        return girlList.size();
    }

    @Override
    public Object getItem(int i) {//获取对应的数据
        return girlList.get(i);
    }

    @Override
    public long getItemId(int i) {//返回索引坐标
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        Girl girl=girlList.get(i);
        ViewHolder viewHolder;
        if(view==null){
            view= inflater.inflate(resourceId,viewGroup,false);
            viewHolder=new ViewHolder();
            viewHolder.imageView=view.findViewById(R.id.item_img);
            viewHolder.textView=view.findViewById(R.id.item_text);
            view.setTag(viewHolder);
        }else{
            viewHolder=(ViewHolder)view.getTag();
        }
        viewHolder.imageView.setImageResource(girl.getId());
        viewHolder.textView.setText(girl.getName());
        return view;

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

核心就是重写四个方法,用法看注释就行啦!比较有意思的是getView中的优化还是和ArrayAdapter一样的,在ViewHolder中下手!点击事件也和ArrayAdapter一样,当然效果图也会是一样的!


三:SimpleAdapter

正如其名,确实但简单,不过还是有几个骚操作,看例子就知道了,别慌:

这次我用GridView来作为载体吧:

GridView的xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SimpleAdapterTest">
    <GridView
        android:id="@+id/gridView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    </GridView>

</LinearLayout>

Java代码如下:

public class SimpleAdapterTest extends AppCompatActivity {
    private List<Map<String,Object>> dataList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple_adapter_test);
        initData();
        initGridView();
    }
    private void initGridView(){
        GridView gridView=findViewById(R.id.gridView);
        gridView.setNumColumns(5);

        SimpleAdapter simpleAdapter=new SimpleAdapter(this,dataList,R.layout.grid_item,
                new String[]{"item_img_id","item_name"},new int[]{R.id.grid_img,R.id.grid_name});
        gridView.setAdapter(simpleAdapter);

        //添加点击事件
        gridView.setOnItemClickListener(new GridView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                ImageView img=view.findViewById(R.id.grid_img);
                img.setImageResource(R.drawable.p5);
                TextView name=view.findViewById(R.id.grid_name);
                name.setText("新垣结衣");
            }
        });

    }
    private void initData(){
        dataList=new ArrayList<>();
        for(int i=0;i<25;i++){
            Map<String,Object> map=new HashMap<>();
            map.put("item_img_id", ConstGirls.imgIds[i%5]);
            map.put("item_name",ConstGirls.girlsName[i%5]);
            dataList.add(map);
        }
    }
}

比较难理解的是from和to,作为String数组的from,传入的是Map中的key值,而to数组为int,分别传入要放入的控件的id值

也不卖关子了,代码中含有监听事件,直接上效果图吧:

然后看一下点击效果:


好了!

终于搞完了!

好吧,还有ViewPaper,Spinner等等组件的适配器,本来想写的,但是好累哎!有时间再说吧,嘿嘿嘿~




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值