Android中包含Header和Footer的無限ListView的實現
Android如果ListView不需要通過點擊Header或者Footer來增加新數據,那還比較簡單。有一種情況是需要通過點擊Header和Footer來向ListView中添加新的數據,這在理論上就是可以包含無限元素的ListView。
我在經曆的兩個項目中都遇到過這種情況,在做第一個項目時,因為經驗不足,走了很多彎路,寫出來的代碼也相當複雜。在我做第二個項目的時候,我對前一次的代碼進行了優化,在滿足要求和性能的同時,代碼量大大減少。
下麵就是包含Header和Footer的無限ListView的一個實現,通過點擊Header或者Footer,可以向ListView中添加數據,這是第一個版本。
1. MainActivity.java
MainActivity的作用是顯示主界麵的ListView。
package com.wubotao.activity; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; import com.wubotao.adapter.StringAdapter; public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_list); ListView listView = (ListView) findViewById(R.id.listview_main); StringAdapter adapter = new StringAdapter(this, listView); listView.setAdapter(adapter); } }
2. AbstractAdapter.java
AbstractAdapter是一個抽象類,實現了BaseAdapter的部分方法。
package com.wubotao.adapter; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.os.Handler; import android.os.Message; import android.widget.BaseAdapter; import android.widget.ListView; /** * * * @author wubotao * * @param <T> * 被存放元素的類型 * * */ public abstract class AbstractAdapter<T> extends BaseAdapter { protected Context context; protected List<T> list = new ArrayList<T>(); protected ListView listView; protected AbstractAdapter(Context context, ListView listView) { this.context = context; this.listView = listView; } public int getCount() { return list == null ? 0 : list.size(); } public Object getItem(int position) { return list.get(position); } public long getItemId(int position) { return position; } protected Handler handler = new Handler() { @Override public void handleMessage(Message msg) { notifyDataSetChanged(); } }; }
3. StringAdapter.java
StringAdapter繼承自AbstractAdapter,主要作用是實現數據和ListView圖形界麵的交互。
package com.wubotao.adapter; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.os.AsyncTask; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ListView; import android.widget.TextView; import android.widget.ViewSwitcher; import com.wubotao.activity.R; /** * * * @author wubotao * */ public class StringAdapter extends AbstractAdapter<String> { boolean headerLoading = false; boolean footerLoading = false; ViewSwitcher footerView; ViewSwitcher headerView; public StringAdapter(Context context, ListView listView) { super(context, listView); LayoutInflater inflater = LayoutInflater.from(context); headerView = (ViewSwitcher) inflater.inflate(R.layout.header, null); listView.addHeaderView(headerView); headerLoading(true); footerView = (ViewSwitcher) inflater.inflate(R.layout.footer, null); new ContentTask().execute(); TextView moreByHeader = (TextView) headerView .findViewById(R.id.textview_to_load_more); moreByHeader.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!headerLoading) { new HeaderTask().execute(); } } }); TextView moreByFooter = (TextView) footerView .findViewById(R.id.textview_to_load_more); moreByFooter.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!footerLoading) { new FooterTask().execute(); } } }); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { viewHolder = new ViewHolder(); LayoutInflater inflater = LayoutInflater.from(context); convertView = inflater.inflate(R.layout.main_list_item, null); viewHolder.content = (TextView) convertView .findViewById(R.id.textview_content); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } String text = (String) getItem(position); viewHolder.content.setText(text); return convertView; } class ViewHolder { TextView content; } class HeaderTask extends AsyncTask<String, Integer, List<String>> { @Override protected void onPreExecute() { headerLoading(true); } @Override protected List<String> doInBackground(String... params) { List<String> list = new ArrayList<String>(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < 3; i++) { list.add("header-" + i); } return list; } @Override protected void onPostExecute(List<String> result) { list.addAll(0, result); notifyDataSetChanged(); headerLoading(false); } } class ContentTask extends AsyncTask<String, Integer, List<String>> { @Override protected List<String> doInBackground(String... params) { List<String> list = new ArrayList<String>(); for (int i = 0; i < 3; i++) { list.add("content-" + i); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return list; } @Override protected void onPostExecute(List<String> result) { list.addAll(0, result); notifyDataSetChanged(); headerLoading(false); listView.addFooterView(footerView); } } class FooterTask extends AsyncTask<String, Integer, List<String>> { @Override protected void onPreExecute() { footerLoading(true); } @Override protected List<String> doInBackground(String... params) { List<String> messages = new ArrayList<String>(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < 3; i++) { list.add("footer-" + i); } return messages; } @Override protected void onPostExecute(List<String> result) { list.addAll(result); notifyDataSetChanged(); footerLoading(false); } } private void footerLoading(boolean isLoading) { if (isLoading) { footerView.setDisplayedChild(1); } else { footerView.setDisplayedChild(0); } footerLoading = isLoading; } private void headerLoading(boolean isLoading) { if (isLoading) { headerView.setDisplayedChild(1); } else { headerView.setDisplayedChild(0); } headerLoading = isLoading; } }裏麵有一些XML在博客上沒法顯示,SVN源碼下載:https://open-source-project-home.googlecode.com/svn/trunk/EndlessListView/
最後更新:2017-04-02 22:16:35
上一篇:
Android添加一個係統service
下一篇:
關於Android 添加係統級(java)服務和調用的編寫實現說明
J2EE中EL和JSTL結合運用
線上性能問題初步排查方法
編寫可讀代碼的藝術
Logic Programming With Prolog學習筆記(一)
Spark On Hbase
利用OTTER實現準實時ETL
QT4靜態編譯後,編譯程序總是通不過,提示“ error: collect2: ld returned 1 exit status”
H5響應式自助建站係統與傳統建站係統有什麼不同
淺談NB-IoT技術對農業物聯網發展的影響
解決方法:java.util.MissingResourceException Can't find bundle for base name