Android学习之ListView与SimpleAdapter的使用

Android学习之ListView与SimpleAdapter的使用

效果图


布局

activity_simple_adapter.xml

   
   
   
   
  1.        android:layout_width="match_parent"
  2.        android:layout_height="wrap_content"
  3.        android:id="@+id/listview"
  4.        />
  5.    

listview_item.xml

   
   
   
   
  1. xml version="1.0" encoding="utf-8"?>
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3.                android:layout_width="match_parent"
  4.                android:layout_height="match_parent"
  5.                android:padding="16dp"
  6.    >
  7.    
  8.        android:layout_width="48dp"
  9.        android:layout_height="48dp"
  10.        android:id="@+id/photo_ib"
  11.        android:layout_alignParentLeft="true"
  12.        />
  13.    
  14.        android:layout_width="wrap_content"
  15.        android:layout_height="24dp"
  16.        android:gravity="center"
  17.        android:id="@+id/username_tv"
  18.        android:layout_toRightOf="@id/photo_ib"
  19.        android:text="@string/app_name"
  20.        android:paddingLeft="8dp"
  21.        android:paddingRight="8dp"
  22.        android:textSize="12sp"
  23.        />
  24.    
  25.        android:layout_width="24dp"
  26.        android:layout_height="24dp"
  27.        android:id="@+id/vip_ib"
  28.        android:layout_toRightOf="@id/username_tv"
  29.        />
  30.    
  31.        android:layout_width="24dp"
  32.        android:layout_height="24dp"
  33.        android:id="@+id/pop_menu_ib"
  34.        android:layout_alignParentRight="true"
  35.        />
  36.    
  37.        android:layout_width="wrap_content"
  38.        android:layout_height="16dp"
  39.        android:gravity="center"
  40.        android:id="@+id/month_tv"
  41.        android:layout_below="@id/username_tv"
  42.        android:layout_toRightOf="@id/photo_ib"
  43.        android:text="1-1"
  44.        android:textSize="12sp"
  45.        android:paddingLeft="8dp"
  46.        android:paddingRight="8dp"
  47.        />
  48.    
  49.        android:layout_width="wrap_content"
  50.        android:layout_height="16dp"
  51.        android:gravity="center"
  52.        android:id="@+id/comefrom_tv"
  53.        android:layout_below="@id/username_tv"
  54.        android:layout_toRightOf="@id/month_tv"
  55.        android:text="来自 "
  56.        android:textSize="12sp"
  57.        android:paddingRight="4dp"
  58.        />
  59.    
  60.        android:layout_width="match_parent"
  61.        android:layout_height="wrap_content"
  62.        android:id="@+id/content_tv"
  63.        android:text="@string/content"
  64.        android:paddingTop="8dp"
  65.        android:paddingBottom="8dp"
  66.        android:textSize="16sp"
  67.        android:layout_below="@id/photo_ib"
  68.        />
  69.    
  70.        android:layout_width="match_parent"
  71.        android:layout_height="wrap_content"
  72.        android:id="@+id/ll"
  73.        android:paddingTop="8dp"
  74.        android:paddingBottom="8dp"
  75.        android:orientation="horizontal"
  76.        android:layout_below="@id/content_tv"
  77.        >
  78.        
  79.            android:layout_width="0dp"
  80.            android:layout_height="wrap_content"
  81.            android:layout_weight="1"
  82.            android:id="@+id/forward_tv"
  83.            android:gravity="center"
  84.            android:textSize="10sp"
  85.            android:text="1"
  86.            />
  87.        
  88.            android:layout_width="0dp"
  89.            android:layout_height="wrap_content"
  90.            android:layout_weight="1"
  91.            android:id="@+id/common_tv"
  92.            android:gravity="center"
  93.            android:textSize="10sp"
  94.            android:text="评论"
  95.            />
  96.        
  97.            android:layout_width="0dp"
  98.            android:layout_height="wrap_content"
  99.            android:layout_weight="1"
  100.            android:id="@+id/praise_tv"
  101.            android:gravity="center"
  102.            android:textSize="10sp"
  103.            android:text="赞"
  104.            />
  105.    

strings.xml

   
   
   
   
  1.     name="content">少的可怜发上来的积分来的是来的是更厉害萨拉合法的三国的塞给了受到法律的塞给了返回搞,士大夫的森林里商大会搞


Activity

   
   
   
   
  1. public class SimpleAdapterActivity extends AppCompatActivity {
  2.    private static final String TAG = "SimpleAdapterActivity";
  3.    private static final String PHOTO = "photo";    // 头像
  4.    private static final String USERNAME = "username";  // 用户名
  5.    private static final String VIP = "vip";    // vip图标
  6.    private static final String POP_MENU = "pop_menu";  // 右侧弹出菜单
  7.    private static final String MONTH = "month";    // 发帖月份,格式1-1
  8.    private static final String COME_FROM = "comefrom"; // 来自。。。
  9.    private static final String CONTENT = "content";    // 贴纸内容
  10.    private ListView mListView;
  11.   private TextView mLoadingTxt;
  12.   private SimpleAdapter mAdapter;
  13.    private List<HashMap<String, Object>> mDatas;   // 每一个map对应listview的一行
  14.    private String[] mFrom; // map的键
  15.    private int[] mTo;      // list item的id数组
  16.    private int mLastVisibleIndex ;  // 列表最后可见的项的索引
  17.    private int mModCount;  // 记录getDatas调用的次数
  18.   private SimpleDateFormat mDateFormat;
  19.    @Override
  20.    protected void onCreate(Bundle savedInstanceState) {
  21.        super.onCreate(savedInstanceState);
  22.        setContentView(R.layout.activity_simple_adapter);    
  23.    // 初始化日期格式
  24.    mDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
  25.    // 初始化listview
  26.    mListView = (ListView) findViewById(R.id.listview);
  27.    // 实例化LinkedList
  28.    mDatas = new LinkedList<>();
  29.    mFrom = new String[]{PHOTO, USERNAME, VIP, POP_MENU, MONTH, COME_FROM, CONTENT};
  30.    mTo = new int[]{R.id.photo_ib, R.id.username_tv, R.id.vip_ib, R.id.pop_menu_ib, R.id.month_tv, R.id.comefrom_tv, R.id.content_tv};
  31.    // 实例化适配器
  32.    mAdapter = new SimpleAdapter(this,
  33.                getDatas(),
  34.                R.layout.listview_item,
  35.                mFrom,
  36.                mTo
  37.                );
  38.    // 绑定数据(图片)到view
  39.    mAdapter.setViewBinder(new SimpleAdapter.ViewBinder() {
  40.    @Override
  41.    public boolean setViewValue(View view, Object data, String textRepresentation) {
  42.    if (view instanceof ImageButton && data instanceof Drawable) {
  43.    ImageButton imageButton = (ImageButton) view;
  44.    imageButton.setImageDrawable((Drawable) data);
  45.    return true;
  46.    }
  47.    return false;
  48.    }
  49.    });

  50.      // 设置listview的适配器
  51.      mListView.setAdapter(mAdapter);
  52.    }
  53.    private Drawable getDrawable(int id, Context context) {
  54.        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  55.            return getResources().getDrawable(id, context.getTheme());
  56.        } else {
  57.        return getResources().getDrawable(id);
  58.        }
  59.    }
  60.    private List<HashMap<String, Object>> getDatas() {
  61.        int i;
  62.        // start i = 1 11 21 31 41
  63.        // end   i = 10 20 30 40 50
  64.        if (mModCount == 0) {
  65.            i = 1;
  66.        } else {
  67.            i = mModCount * 10 + 1;
  68.        }
  69.        for (; i <= mModCount *10+10; i++) {
  70.            HashMap<String, Object> map = new HashMap<>();
  71.            map.put(PHOTO, getDrawable(R.mipmap.ic_launcher, this));
  72.            map.put(USERNAME, "等风的草"+i+"号");
  73.            map.put(VIP, getDrawable(R.drawable.vip, this));
  74.            map.put(POP_MENU, getDrawable(R.drawable.pop_pic, this));
  75.            map.put(MONTH, mDateFormat.format(new Date()));
  76.            map.put(COME_FROM, "微博weibo"+i);
  77.            map.put(CONTENT, getResources().getString(R.string.content));
  78.            mDatas.add(map);
  79.        }
  80.       mModCount++;
  81.        return mDatas;
  82.    }
  83. }


设置监听listview滚动状态

    
    
    
    
  1. mListView.setOnScrollListener(this);

实现接口

    
    
    
    
  1. AbsListView.OnScrollListener


实现模拟网络数据自动加载.

/*
     监听器滚动状态
      SCROLL_STATE_TOUCH_SCROLL:正在滚动
      SCROLL_STATE_IDLE:空闲状态
      */
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // 当当前可见索引是列表最后一个并且不滚动时,加载数据
        if (mLastVisibleIndex == mAdapter.getCount() - 1 && scrollState == SCROLL_STATE_IDLE) {
	        mListView.addFooterView(mLoadingTxt); // 添加页脚(放在ListView最后)

	        // simple adapter实现分页加载
	        // 另起一个线程加载
	        new Thread(new Runnable() {
				@Override
		        public void run() {
					try {
						Thread.sleep(2000);
						getDatas();

						runOnUiThread(new Runnable() {
							@Override
							public void run() {
								mAdapter.notifyDataSetChanged();

								if (mListView.getFooterViewsCount() > 0)
									mListView.removeFooterView(mLoadingTxt);   // 加载完数据后移除页脚
							}
						});

						Log.d(TAG, "onScrollStateChanged: 模拟网络数据加载。。。");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
		  }).start();

        }
    }

    /*
		firstVisibleItem:列表第一个可见索引
		visibleItemCount:列表可见数
     */

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        mLastVisibleIndex = firstVisibleItem + visibleItemCount - 1;
    }


在onCreate方法中添加自动加载时的提示

   
   
   
   
  1. mLoadingTxt = new TextView(this);
  2. mLoadingTxt.setText(R.string.loading_text);
  3. mLoadingTxt.setGravity(Gravity.CENTER);
  4. mLoadingTxt.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));  // 字体加粗

strings.xml

   
   
   
   
  1.   name="loading_text">加载中...

在onCreate方法中,添加提示

    
    
    
    
  1. // 要确保自己的addHeaderView(view)和addFooterView(view)方法是在ListView.setAdapter(adapter)之前执行,否则会报以下异常
  2. // java.lang.ClassCastException:android.widget.SimpleAdapter cannot be cast to android.widget.HeaderViewListAdapter
  3. mListView.addFooterView(mLoadingTxt);
  4. // 设置listview的适配器
  5. mListView.setAdapter(mAdapter);
  6. mListView.removeFooterView(mLoadingTxt);


最后贴上完整清单

public class SimpleAdapterActivity extends AppCompatActivity implements AbsListView.OnScrollListener {

    private static final String TAG = "SimpleAdapterActivity";
    private static final String PHOTO = "photo";    // 头像
    private static final String USERNAME = "username";  // 用户名
    private static final String VIP = "vip";    // vip图标
    private static final String POP_MENU = "pop_menu";  // 右侧弹出菜单
    private static final String MONTH = "month";    // 发帖月份,格式1-1
    private static final String COME_FROM = "comefrom"; // 来自。。。
    private static final String CONTENT = "content";    // 贴纸内容

    private ListView mListView;
	private	TextView mLoadingTxt;

	private SimpleAdapter mAdapter;
    private List> mDatas;   // 每一个map对应listview的一行
    private String[] mFrom; // map的键
    private int[] mTo;      // list item的id数组
    private int mLastVisibleIndex ;  // 列表最后可见的项的索引
    private int mModCount;  // 记录getDatas调用的次数
	private SimpleDateFormat mDateFormat;

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

	    // ViewStub viewStub = (ViewStub)findViewById(R.id.footerview_stub);  // 需要时才加载
 	    mLoadingTxt = new TextView(this);
	    mLoadingTxt.setText(R.string.loading_text);
	    mLoadingTxt.setGravity(Gravity.CENTER);
	    mLoadingTxt.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));  // 字体加粗

	    // 初始化日期格式
	    mDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);

	    // 初始化listview
	    mListView = (ListView) findViewById(R.id.listview);
	    // 实例化LinkedList
	    mDatas = new LinkedList<>();
	    mFrom = new String[]{PHOTO, USERNAME, VIP, POP_MENU, MONTH, COME_FROM, CONTENT};
	    mTo = new int[]{R.id.photo_ib, R.id.username_tv, R.id.vip_ib, R.id.pop_menu_ib, R.id.month_tv, R.id.comefrom_tv, R.id.content_tv};
	    // 实例化适配器
	    mAdapter = new SimpleAdapter(this,
                getDatas(),
                R.layout.listview_item,
                mFrom,
                mTo
                );

	    // 绑定数据(图片)到view
	    mAdapter.setViewBinder(new SimpleAdapter.ViewBinder() {
		    @Override
		    public boolean setViewValue(View view, Object data, String textRepresentation) {
			    if (view instanceof ImageButton && data instanceof Drawable) {
				    ImageButton imageButton = (ImageButton) view;
				    imageButton.setImageDrawable((Drawable) data);
				    return true;
			    }
			    return false;
		    }
	    });

	    // 要确保自己的addHeaderView(view)和addFooterView(view)方法是在ListView.setAdapter(adapter)之前执行,否则会报以下异常
	    // java.lang.ClassCastException:android.widget.SimpleAdapter cannot be cast to android.widget.HeaderViewListAdapter
	    mListView.addFooterView(mLoadingTxt);
        // 设置listview的适配器
        mListView.setAdapter(mAdapter);
	    mListView.removeFooterView(mLoadingTxt);
        mListView.setOnScrollListener(this);
    }


    private Drawable getDrawable(int id, Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            return getResources().getDrawable(id, context.getTheme());
        } else {
	        return getResources().getDrawable(id);
        }
    }

    private List> getDatas() {
        int i;
        // start i = 1 11 21 31 41
        // end   i = 10 20 30 40 50
        if (mModCount == 0) {
            i = 1;
        } else {
            i = mModCount * 10 + 1;
        }

        for (; i <= mModCount *10+10; i++) {
            HashMap map = new HashMap<>();
            map.put(PHOTO, getDrawable(R.mipmap.ic_launcher, this));
            map.put(USERNAME, "等风的草"+i+"号");
            map.put(VIP, getDrawable(R.drawable.vip, this));
            map.put(POP_MENU, getDrawable(R.drawable.pop_pic, this));
            map.put(MONTH, mDateFormat.format(new Date()));
            map.put(COME_FROM, "微博weibo"+i);
            map.put(CONTENT, getResources().getString(R.string.content));

            mDatas.add(map);
        }

	    mModCount++;
        return mDatas;
    }


    /*
     监听器滚动状态
      SCROLL_STATE_TOUCH_SCROLL:正在滚动
      SCROLL_STATE_IDLE:空闲状态
      */
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // 当当前可见索引是列表最后一个并且不滚动时,加载数据
        if (mLastVisibleIndex == mAdapter.getCount() - 1 && scrollState == SCROLL_STATE_IDLE) {
	        mListView.addFooterView(mLoadingTxt); // 添加页脚(放在ListView最后)

	        // simple adapter实现分页加载
	        // 另起一个线程加载
	        new Thread(new Runnable() {
				@Override
		        public void run() {
					try {
						Thread.sleep(2000);
						getDatas();

						runOnUiThread(new Runnable() {
							@Override
							public void run() {
								mAdapter.notifyDataSetChanged();

								if (mListView.getFooterViewsCount() > 0)
									mListView.removeFooterView(mLoadingTxt);   // 加载完数据后移除页脚
							}
						});

						Log.d(TAG, "onScrollStateChanged: 模拟网络数据加载。。。");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
		  }).start();

        }
    }

    /*
		firstVisibleItem:列表第一个可见索引
		visibleItemCount:列表可见数
     */

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        mLastVisibleIndex = firstVisibleItem + visibleItemCount - 1;
    }
}



如有疑问请指出交流,谢谢!

你可能感兴趣的:(Android初级)