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