activity_simple_adapter.xml
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/listview"
/>
listview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
>
<ImageButton
android:layout_width="48dp"
android:layout_height="48dp"
android:id="@+id/photo_ib"
android:layout_alignParentLeft="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="24dp"
android:gravity="center"
android:id="@+id/username_tv"
android:layout_toRightOf="@id/photo_ib"
android:text="@string/app_name"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textSize="12sp"
/>
<ImageButton
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/vip_ib"
android:layout_toRightOf="@id/username_tv"
/>
<ImageButton
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/pop_menu_ib"
android:layout_alignParentRight="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="16dp"
android:gravity="center"
android:id="@+id/month_tv"
android:layout_below="@id/username_tv"
android:layout_toRightOf="@id/photo_ib"
android:text="1-1"
android:textSize="12sp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="16dp"
android:gravity="center"
android:id="@+id/comefrom_tv"
android:layout_below="@id/username_tv"
android:layout_toRightOf="@id/month_tv"
android:text="来自 "
android:textSize="12sp"
android:paddingRight="4dp"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/content_tv"
android:text="@string/content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:textSize="16sp"
android:layout_below="@id/photo_ib"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/ll"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:orientation="horizontal"
android:layout_below="@id/content_tv"
>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/forward_tv"
android:gravity="center"
android:textSize="10sp"
android:text="1"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/common_tv"
android:gravity="center"
android:textSize="10sp"
android:text="评论"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/praise_tv"
android:gravity="center"
android:textSize="10sp"
android:text="赞"
/>
</LinearLayout>
</RelativeLayout>
strings.xml
<string name="content">少的可怜发上来的积分来的是来的是更厉害萨拉合法的三国的塞给了受到法律的塞给了返回搞,士大夫的森林里商大会搞</string>
public class SimpleAdapterActivity extends AppCompatActivity {
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<HashMap<String, Object>> 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);
// 初始化日期格式
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;
}
});
- // 设置listview的适配器
mListView.setAdapter(mAdapter);
}
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<HashMap<String, Object>> 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<String, Object> 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;
}
}
设置监听listview滚动状态
mListView.setOnScrollListener(this);
实现接口
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方法中添加自动加载时的提示
mLoadingTxt = new TextView(this);
mLoadingTxt.setText(R.string.loading_text);
mLoadingTxt.setGravity(Gravity.CENTER);
mLoadingTxt.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD)); // 字体加粗
strings.xml
<string name="loading_text">加载中...</string>
在onCreate方法中,添加提示
// 要确保自己的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);
最后贴上完整清单
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<HashMap<String, Object>> 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<HashMap<String, Object>> 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<String, Object> 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; } }
如有疑问请指出交流,谢谢!