zoukankan      html  css  js  c++  java
  • ListView配合BaseAdapter

      BaseAdapter使用比较麻烦,它是个抽象类,需要重写4个方法分别是getCount() getItem(..) getItemId(..) getVew(..),相应的使用BaseAdapter

    可以自由的定义自己想要的布局,先看看程序效果图:

    这个布局一共有5个元素分别是:ImageViw 2个TextView CheckBox Button

    先看这个ListView的Item布局文件list_item.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_gravity="center_horizontal"
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:src="@drawable/ic_launcher"
            android:id="@+id/iv_image"/>
        <!-- 注意这个里两个TextView的布局是垂注布局的-->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_weight="4">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:textSize="25dp"
                android:text="hah"
                android:id="@+id/tv_item"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="content"
                android:id="@+id/tv_content"/>
        </LinearLayout>
    
        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:id="@+id/ck_box"
            />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textSize="20sp"
            android:text="Select"
            android:id="@+id/btn_select"
            android:background="@drawable/btn_selector"/>
    </LinearLayout>
    View Code

    整理一下我们要做的事情:1、首先在主布局里要放一个ListView;
                2、准备ListView显示需要的数据;

                                     3、重写适配器,将布局文件与数据放到ListView中显示,这一部分最复杂,还有布局文件中还有点击事件需要设置。

    下面是主程序代码:

    package com.skymaster.hs.baseadaptertest;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.Button;
    import android.widget.CheckBox;
    import android.widget.ImageView;
    import android.widget.ListView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    
    public class MainActivity extends AppCompatActivity {
        private ListView listView;
        private HsAdapter hsAdapter;
        private ArrayList<HashMap<String,Object>> listItem;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            listView = (ListView) findViewById(R.id.lv_list);
            hsAdapter = new HsAdapter(getLayoutInflater());
            DataInit();
            listView.setAdapter(hsAdapter);
        }
        /*
        * 初始化显示的内容ListView表的数据结构对应的是ArrayList
        * 但是ListView内部每一项Item有细分多个View,所以ArrayList泛型定义为Map
        * 这样就可以定义多中数据类型了,没一个key对应一个View,适配器在填充内容的时候
        * 可以根据key来获取内容,这里要注意一点:HashMap<String,Object> hashMap = new HashMap<>();
        * 一定要放到循环里面,因为ListView有多少个Item就应该有多少个数据对象也就是说有多少new出来得对象实例
        * */
        private void DataInit(){
            listItem = new ArrayList<>();
            for(int i=0;i<10;i++){
                HashMap<String,Object> hashMap = new HashMap<>();
                hashMap.put("title","title:"+i);
                hashMap.put("content","content:"+i);
                hashMap.put("image",image_index[i]);
                listItem.add(hashMap);
            }
        }
        /*
        * 这里定义ImageView的数组索引,适配器在设置ImageView背景的时候使用比较方便
        * */
        private final int[] image_index = {
                R.drawable.ic_launcher,
                R.drawable.image1,
                R.drawable.image2,
                R.drawable.image3,
                R.drawable.image4,
                R.drawable.image5,
                R.drawable.image6,
                R.drawable.image7,
                R.drawable.image8,
                R.drawable.image9,
        };
        /*
        * convertView配合ViewHolder可以提高UI加载的效率,这里定义成static型
        * 相当于全局保存布局文件中的View对象实例。
        * */
        static class ViewHolder{
            TextView tv_item;
            TextView tv_content;
            ImageView iv_image;
            Button btn_select;
            CheckBox ck_box;
        }
    
        private class HsAdapter extends BaseAdapter{
            /*
             * 这里需要解释一下LayoutInflater的用法:/**
             * Instantiates a layout XML file into its corresponding {@link android.view.View}
             * objects. It is never used directly. Instead, use
             * {@link android.app.Activity#getLayoutInflater()} or
             * {@link Context#getSystemService} to retrieve a standard LayoutInflater instance
             * that is already hooked up to the current context and correctly configured
             * for the device you are running on.
             * 以上是源码的注释
             * 首先这个是一个抽象对象,所以从来不会直接实例化来引用,而且它也没有任何的子类。
             * 所以要使用这个类,唯一的办法就是:1、从Activity.getLayoutInflater()中获得
             *                               2、从上下文Context.getSystemService找回当前上下文连接的
             *                                LayoutInflater实例。
             *  eg:LayoutInflater inflater = (LayoutInflater)context.getSystemService
             *      (Context.LAYOUT_INFLATER_SERVICE)
             * 因此我们设置适配器构造函数的时候传入了Activity的布局解析器
             * */
            private LayoutInflater mInflator;
            private ViewHolder viewHolder;
            public HsAdapter(LayoutInflater mInflator){
                this.mInflator = mInflator;
            }
            @Override
            public int getCount() {
                return listItem.size();
            }
    
            @Override
            public Object getItem(int position) {
                System.out.println("getItem");
                return null;
            }
    
            @Override
            public long getItemId(int position) {
                System.out.println("getItemId:"+position);
                return 0;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                if(convertView == null){
                    /*
                    * 1.这段代码执行的次数与ListView的项数有关系,如果手机屏幕最大显示数目是6个,那么执行的次数
                    * 就是7次,最后会保留一个convertView实例在viewHolder中,并且保存在convertView的Tag中,
                    * 这样做的目的是当ListView滑动,显示变化需要加载新的Item的时候可以不用再执行这一段代码
                    * 直接用tag中保存的引用来填充Item,提高效率。这就是setTag()的目的。
                    * 2.注意viewHolder = new ViewHolder();与convertView = mInflator.inflate(R.layout.list_item, null);
                    * 是对应的,不然会引起空指针错误。
                    * 3.一段代码加载的原理就是:在ListView初始化的时候每加载一项Item都会执行一次getView,并且这个时候
                    * convertView都是空,如果反过来理解其实每一项viewHolder的引用都必须通过findViewById来指向一个实例,不然就会报错。
                    * 当屏幕最大显示的6项加载完毕,在多保留一个viewHolder引用备用就不会执行了。这个时候如果滑动ListView
                    * 需要加载新的Item,这个时候又会调用getView,而这个时候会直接用预留的一个convertView。如果继续滑动,
                    * 这个时候convertView并不为空,这是因为滑动的过程中除了会出现新的Item,旧的Item会移出屏幕不在显示,这个时候
                    * convertView其实装载的是旧的引用,如此循环,因此可以判断如果手机整个屏幕ListView最大显示的
                    * item的数据是n那么convertView的引用数据就是n+1了
                    * */
                    viewHolder = new ViewHolder();
                    convertView = mInflator.inflate(R.layout.list_item, null);
                    viewHolder.tv_item = (TextView)convertView.findViewById(R.id.tv_item);
                    viewHolder.iv_image = (ImageView)convertView.findViewById(R.id.iv_image);
                    viewHolder.tv_content = (TextView)convertView.findViewById(R.id.tv_content);
                    viewHolder.btn_select = (Button)convertView.findViewById(R.id.btn_select);
                    viewHolder.ck_box = (CheckBox)convertView.findViewById(R.id.ck_box);
    
                    viewHolder.btn_select.setTag(position);//设置按键的 Tag辅助判断是哪一个按键按下,因为这里所有项的按键实体id只有一个所有需要
                                                           //position来辅助判断
                    viewHolder.btn_select.setOnClickListener(new KeyPressService());//设置按键监听一定要放在里面,因为getView调用的次数非常多
                                                                                    //而我们只需要对有效Item的按键设置监听。
                    viewHolder.ck_box.setTag(position);//同理按键
                    viewHolder.ck_box.setOnClickListener(new KeyPressService());//同理按键
    
                    convertView.setTag(viewHolder);//保存引用
                }else{
                    viewHolder = (ViewHolder)convertView.getTag();
                    viewHolder.btn_select.setTag(position);
                    viewHolder.btn_select.setOnClickListener(new KeyPressService());
                    viewHolder.ck_box.setOnClickListener(new KeyPressService());
                    viewHolder.ck_box.setTag(position);
                }
                /*
                 * 这里就是适配器绑定数据源与View的过程。利用Map的数据结构可以方便找到
                 * 因为是HashMap<String,Object>返回的value是object所以要强转
                 * */
                viewHolder.iv_image.setBackgroundResource((Integer) listItem.get(position).get("image"));
                viewHolder.tv_item.setText((String) listItem.get(position).get("title"));
                viewHolder.tv_content.setText((String) listItem.get(position).get("content"));
    
                return convertView;
            }
        }
    
        private class KeyPressService implements View.OnClickListener{
            @Override
            public void onClick(View v) {
                switch (v.getId()){
                    case R.id.btn_select:
                        ClickEventProcess(v,"Button");
                        break;
                    case R.id.ck_box:
                        ClickEventProcess(v,"checkbox");
                        break;
                }
    
            }
            private void ClickEventProcess(View v,String str){
    
                switch ((Integer)v.getTag()){
                    case 0:
                        Toast.makeText(MainActivity.this,"click:0"+str,Toast.LENGTH_SHORT)
                                .show();
                        break;
                    case 1:
                        Toast.makeText(MainActivity.this,"click:1"+str,Toast.LENGTH_SHORT)
                                .show();
                        break;
                    case 2:
                        Toast.makeText(MainActivity.this,"click:2"+str,Toast.LENGTH_SHORT)
                                .show();
                        break;
                    case 3:
                        Toast.makeText(MainActivity.this,"click:3"+str,Toast.LENGTH_SHORT)
                                .show();
                        break;
                    case 4:
                        Toast.makeText(MainActivity.this,"click:4"+str,Toast.LENGTH_SHORT)
                                .show();
                        break;
                    case 5:
                        Toast.makeText(MainActivity.this,"click:5"+str,Toast.LENGTH_SHORT)
                                .show();
                        break;
                    case 6:
                        Toast.makeText(MainActivity.this,"click:6"+str,Toast.LENGTH_SHORT)
                                .show();
                        break;
                    case 7:
                        Toast.makeText(MainActivity.this,"click:7"+str,Toast.LENGTH_SHORT)
                                .show();
                        break;
                    case 8:
                        Toast.makeText(MainActivity.this,"click:8"+str,Toast.LENGTH_SHORT)
                                .show();
                        break;
                    case 9:
                        Toast.makeText(MainActivity.this,"click:9"+str,Toast.LENGTH_SHORT)
                                .show();
                        break;
                }
            }
        }
    }
    View Code

    下面是程序执行的效果:

    主界面的布局activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.skymaster.hs.baseadaptertest.MainActivity">
    
        <ListView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/lv_list"/>
    </RelativeLayout>

    按键的drawable文件btn_normal.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <corners android:radius="45dp"/>
        <size android:height="10dp"
            android:width="30dp"/>
        <solid android:color="@color/colorPrimary"/>
    </shape>

    btn_press.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <corners android:radius="45dp"/>
        <size android:height="10dp"
            android:width="30dp"/>
        <solid android:color="@color/colorPrimary"/>
        <stroke android:color="#ff0000"
            android:width="10dp"/>
    </shape>

    btn_selector.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true" android:drawable="@drawable/btn_press"/>
        <item android:state_pressed="false" android:drawable="@drawable/btn_normal"/>
    </selector>
    这个只不过是自己的流水账,偶尔有一些心得,错误的地方概不负责
  • 相关阅读:
    Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)
    IP地址资源的分配和管理
    破解中常见的指令及修改
    8086 CPU 寻址方式
    汇编指令速查
    关于ida pro的插件keypatch
    动态方式破解apk进阶篇(IDA调试so源码)
    IDA7.0安装keypatch和findcrypt-yara插件
    Android逆向之旅---动态方式破解apk进阶篇(IDA调试so源码)
    IDA动态调试技术及Dump内存
  • 原文地址:https://www.cnblogs.com/ashitaka/p/5893311.html
Copyright © 2011-2022 走看看