第一步:放入XListView依托的三个文件:XListView、XListViewFooter、XListViewHeader;放入XListViewFooter.java和XListViewHeader.java依托的布局文件xlistview_footer.xml,xlistview_header.xml文件。这5个文件的下载地址:http://pan.baidu.com/s/1c0com4o
在布局文件中可以把ProgressBar换成类是贴吧那样的Button。
第二步:在布局文件中的使用:
<com.tugepclp_driver.widget.XListView android:id="@+id/hint_tab_list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:layout_marginLeft="10dp" android:layout_below="@+id/top_layout" android:cacheColorHint="#00000000" android:divider="@android:color/transparent" android:dividerHeight="0dp" android:fadingEdge="none" android:footerDividersEnabled="false" android:headerDividersEnabled="false" android:listSelector="#00000000" android:scrollbars="none"> </com.tugepclp_driver.widget.XListView>
第三步:重写Activity并在此类中写入adapter内部类,见下源码,类名AdapterActivity
说明:
①在这个父类中包含了定义的adapter和listView,还有数据listData、内部类自写的Adapter
②拥有了abstract类型的方法(即必须重写,且只有方法名,没有方法体),这些方法有setLayoutView(添加布局父类onCreate调用)、getView(填充数据,由内部类adapter的getView方法调用)、onItemClick(listView单击事件,由父类的onCreate方法调用)
③传数据:setListView(传listView给父类)、isItemEnabled(是否开启某个item的单击事件)、onCreate(调用setLayoutView和写listView.setOnItemClickListener(调用onItemClick))
④内部类:Adapter,继承SimpleAdapter。包含了构造函数 public Adapter(Context context){}、 public int getCount(){获取listView长度}、 public boolean isEnabled(int position){调用isItemEnabled}、 public View getView{调用getView}
import java.util.ArrayList; import java.util.List; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.SimpleAdapter; import com.tugepclp_driver.widget.EmptyViewUtils; public abstract class AdapterActivity<T> extends BaseActivity { public static final int TYPE_LISTVIEW = 0; public static final int TYPE_GRIDVIEW = 0; public Adapter adapter;//自定义Adapter //for empty view private View mEmptyLoadingView = null; private View mEmptyFailView = null; protected AbsListView listView;//父类listView public AbsListView getListView() { return listView; } /** * setListView */ public void setListView(int resId) { this.listView = (AbsListView) findViewById(resId); } /** * 数据 */ protected List<T> listData = new ArrayList<T>(); /** * setContentView(int resId) * setListView(int resId) * 添加布局,父类onCreate调用 */ protected abstract void setLayoutView(); /** * the adapter's getView() method * * @param position * @param convertView * @return 填充数据,由adapter的getView方法调用 */ protected abstract View getView(int position, View convertView); /** * 禁用单击事件 */ protected boolean isItemEnabled(int position) { return true; } /** * the listView's item click event * * @param adapterView * @param view * @param position * @param id 设定listView的单击事件,由父类的onCreate方法调用 */ protected abstract void onItemClick(AdapterView<?> adapterView, View view, int position, long id); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setLayoutView(); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { AdapterActivity.this.onItemClick(adapterView, view, position, id); } }); } /** * 内部类Adapter */ public class Adapter extends SimpleAdapter { public Adapter(Context context) { super(context, null, 0, null, null); } /** * 获取listView长度 */ @Override public int getCount() { return listData.size(); } /** * 禁用单击事件 */ @Override public boolean isEnabled(int position) { return AdapterActivity.this.isItemEnabled(position); } /** * 填充数据,调用AdapterActivity内的getView方法 */ @Override public View getView(int position, View convertView, ViewGroup parent) { return AdapterActivity.this.getView(position, convertView); } } //show loading view when init and loading data from network protected void showLoadingEmptyView() { if (mEmptyFailView == null) { mEmptyLoadingView = EmptyViewUtils.createLoadingView(this); } ((ViewGroup) listView.getParent()).removeView(mEmptyFailView); ((ViewGroup) listView.getParent()).addView(mEmptyLoadingView); listView.setEmptyView(mEmptyLoadingView); } //show fail view when loading data fail protected void showFailEmptyView() { if (mEmptyFailView == null) { mEmptyFailView = EmptyViewUtils.createFailView(this); } ((ViewGroup) listView.getParent()).removeView(mEmptyLoadingView); ((ViewGroup) listView.getParent()).addView(mEmptyFailView); listView.setEmptyView(mEmptyFailView); } }
BaseActivity:.java文件:
package com.tugepclp_driver.activity; import android.app.Activity; import android.app.Dialog; import android.os.Bundle; import android.view.Gravity; import android.view.Window; import android.widget.Toast; import com.baidu.mobstat.StatService; import com.tugepclp_driver.utils.DialogFactory; public class BaseActivity extends Activity { private Toast mToast; /** * 点击登录按钮后,弹出验证对话框 */ public Dialog mDialog = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏 StatService.setSessionTimeOut(30); } @Override protected void onResume() { super.onResume(); StatService.onResume(this); } @Override protected void onPause() { super.onPause(); StatService.onPause(this); } public void showRequestDialog(String msg) { if (mDialog != null) { mDialog.dismiss(); mDialog = null; } mDialog = DialogFactory.creatRequestDialog(this, msg); // mDialog.setCancelable(false); mDialog.setCanceledOnTouchOutside(false); mDialog.show(); } public void closeRequestDialog() { if (mDialog != null) { mDialog.dismiss(); mDialog = null; } } @Override public void onBackPressed() { super.onBackPressed(); finish(); } public void alert(String msg) { // if (SysBaseData.getInstance().showAlert) { if (mToast == null) { mToast = Toast.makeText(getApplicationContext(), msg, 1000); mToast.setGravity(Gravity.CENTER, 0, 0); } else { mToast.setText(msg); mToast.setDuration(1000); } mToast.show(); // } } }
DialogFactory.java文件:
package com.tugepclp_driver.utils; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.view.Window; import android.view.WindowManager; import android.widget.TextView; import com.tugepclp_driver.R; public class DialogFactory { public static Dialog creatRequestDialog(final Context context, String tip) { final Dialog dialog = new Dialog(context, R.style.dialog); // dialog.setCancelable(false); // dialog.setCanceledOnTouchOutside(false); dialog.setContentView(R.layout.dialog_layout); Window window = dialog.getWindow(); WindowManager.LayoutParams lp = window.getAttributes(); int width = Utils.getScreenWidth(context); lp.width = (int) (0.5 * width); TextView titleTxtv = (TextView) dialog.findViewById(R.id.tvLoad); titleTxtv.setText(tip); return dialog; } public static void ToastDialog(Context context, String title, String msg) { new AlertDialog.Builder(context).setTitle(title).setMessage(msg) .setPositiveButton("确定", null).create().show(); } }
第四步:继承AdapterActivity实现了XListView.IXListViewListener:
public class HintActivity extends AdapterActivity<HintModel>implements XListView.IXListViewListener
说明:
①重写了第三步中的所有abstract的方法
②首先调用 initVariable();//从xml文件中获取存储的数据,userID和mobile-token
③调用initView();获取一些布局ID
④重写XListView.IXListViewListener的刷新方法onRefresh(),加载更多方法onLoadMore()。注意:加载更多中需要总数totalCount,故在第一次获取数据或者刷新时获取接口提供的这个值。
⑤主要的是获取数据loadData()方法,详见笔记中的网络数据的获取(获取JSON数据)
⑥获取数据后就要解析填充了,这个方法是setList( ),而且在此时更新字段lastRefreshTime,即上次更新时间。
⑦对象的定义字段名字要与提供的接口名字相同
⑧由于锁屏被掩盖activity之类的原因,重新activity的方法onResume{重新启动界面时,重新更新数据}
import android.content.Intent; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.*; import com.google.gson.Gson; import com.tugepclp_driver.R; import com.tugepclp_driver.config.AppApplication; import com.tugepclp_driver.config.AppConfig; import com.tugepclp_driver.model.HintModel; import com.tugepclp_driver.syns.http.AsyncHttpClient; import com.tugepclp_driver.syns.http.AsyncHttpResponseHandler; import com.tugepclp_driver.utils.DateUtil; import com.tugepclp_driver.utils.PreferencesUtils; import com.tugepclp_driver.widget.XListView; import org.apache.http.entity.ByteArrayEntity; import org.json.JSONArray; import org.json.JSONObject; import java.lang.reflect.Type; import java.util.List; /** * Created by ccddy on 14-8-28. */ public class HintActivity extends AdapterActivity<HintModel> implements XListView.IXListViewListener { private XListView mListView; private int pageIndex = 0; private int pagesize = 10; private int totalCount = 0; private String lastRefreshTime; private static final String TASK_URL = AppConfig.SERVERURL + "MessageNoticeSearch"; private int mUserID; private String mTicket; private ImageButton ibtnBack; private TextView tvTitle; private String mType; private String mStatus; private LinearLayout layLoading; private int[] allID; private View line; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AppApplication.getInstance().addActivity(this); initVariable();//从xml文件中获取存储的数据,userID和mobile-token initView(); } /** * 重新启动界面时,重新更新数据 */ @Override protected void onResume() { super.onResume(); mListView.setVisibility(View.GONE); line.setVisibility(View.GONE); loadCache(); } /** * 从xml文件中获取存储的数据,userID和mobile-token */ private void initVariable() { mUserID = PreferencesUtils.getIntPreference(this, "UserID", 0); mTicket = PreferencesUtils.getStringPreference(this, "Ticket", ""); } private void initView() { layLoading = (LinearLayout) findViewById(R.id.app_loading);//获取布局的ID,是否显示此布局 } /** * 等待缓存 */ private void loadCache() { loadData(); } /** * 等待回去数据 */ private void loadData() { try { AsyncHttpClient client = new AsyncHttpClient(); JSONObject object = new JSONObject(); object.put("userID", mUserID); object.put("pageIndex", pageIndex); object.put("pageSize", pagesize); object.put("ticket", mTicket); byte[] bytes = object.toString().getBytes("utf-8"); ByteArrayEntity stringEntity = new ByteArrayEntity(bytes); client.post(this, TASK_URL, stringEntity, "application/json", new AsyncHttpResponseHandler() { @Override // 开始加载数据 public void onStart() { layLoading.setVisibility(View.VISIBLE); } @Override // 加载数据成功 public void onSuccess(String result) { line.setVisibility(View.VISIBLE); if (setList(result)) { } else { alert("数据加载失败..."); } onLoad(); } @Override // 加载数据失败 public void onFailure(Throwable error) { // listView.setAdapter(null); listView.setVisibility(View.INVISIBLE); onLoad(); alert("网络不稳定、数据加载失败..."); // TODO 顶部现实网络问题� } @Override public void onFinish() { super.onFinish(); mListView.setVisibility(View.VISIBLE); } } ); } catch (Exception e) { e.printStackTrace(); } } /** * XListView停止刷新、加载更多、更新上次刷新时间,去掉加载更多图标 */ private void onLoad() { mListView.stopRefresh(); mListView.stopLoadMore(); mListView.setRefreshTime(lastRefreshTime);//只有获取成功时才更新上次更新时间 layLoading.setVisibility(View.GONE); } private boolean setList(String cacheConfigString) { try { JSONObject json = new JSONObject(cacheConfigString); if (json.getString("State").equals("1")) { JSONArray array = json.getJSONArray("Data"); if (array.length() > 0) { lastRefreshTime = DateUtil.getCurrentDateTime();//上次更新时间 Type type = new com.google.gson.reflect.TypeToken<List<HintModel>>() { }.getType(); listData = new Gson().fromJson(array.toString(), type); allID = new int[listData.size()]; for (int i = 0; i < allID.length; i++) { allID[i] = listData.get(i).MessageNoticeID; } if (pageIndex == 0) { adapter = new AdapterActivity.Adapter(this); ((ListView) listView).setAdapter(adapter); } else { adapter.notifyDataSetChanged(); } } return true; } } catch (Exception e) { e.printStackTrace(); } return false; } /** * XListView.IXListViewListener的刷新方法 */ @Override public void onRefresh() { View line = findViewById(R.id.hint_line); line.setVisibility(View.GONE); // listData.clear();刷新时需要清除数据时再清除,一般不用 pageIndex = 0; loadData(); } /** * XListView.IXListViewListener的加载更多方法 */ @Override public void onLoadMore() { int page = (int) Math.ceil((double) totalCount / (double) pagesize);//将小说位一律向整数进位,如 Math.ceil(12.2)=13, Math.ceil(12.0)=12 if (pageIndex + 1 < page) { line.setVisibility(View.GONE); pageIndex++; loadData(); } else { onLoad(); line.setVisibility(View.VISIBLE); alert("没有更多消息"); } } /** * AdapterActivity的设置界面方法,因为重写了onCreate方法,故父类调用此方法 */ @Override protected void setLayoutView() { setContentView(R.layout.hint_activity); setListView(R.id.hint_tab_list);//使得mListView和父类的ListView相同 mListView = (XListView) findViewById(R.id.hint_tab_list); mListView.setPullLoadEnable(true);//启用或禁止加载更多 mListView.setXListViewListener(this);//单击事件 ibtnBack = (ImageButton) findViewById(R.id.ibtnBack); ibtnBack.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); line = findViewById(R.id.hint_line); } /** * AdapterActivity的getView方法,父类中的内部类Adapter调用了此方法,在此实现填充数据 */ @Override protected View getView(final int position, View convertView) { if (convertView == null) { convertView = LinearLayout.inflate(getApplication(), R.layout.hint_list_item, null); } final HintModel model = listData.get(position); ImageButton imForm = (ImageButton) convertView.findViewById(R.id.hint_form); TextView tvForm = (TextView) convertView.findViewById(R.id.form); tvForm.setText("系统提示"); TextView tvTime = (TextView) convertView.findViewById(R.id.hint_time); tvTime.setText(model.CreateTime); TextView tvDialog = (TextView) convertView.findViewById(R.id.hint_dialog); tvDialog.setText(model.MessageTitle); tvDialog.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(HintActivity.this, MessageInfoActivity.class); intent.putExtra("position", position); intent.putExtra("ID", allID[position]); intent.putExtra("allID", allID); startActivity(intent); } }); // Log.e("---------messagestate----", model.MessageState + ""); if (model.MessageState == 0) { imForm.setBackgroundResource(R.drawable.hint_syatem); tvForm.setTextColor(Color.BLACK); tvTime.setTextColor(Color.BLACK); tvDialog.setTextColor(Color.BLACK); } return convertView; } /** * XListView的单击时间 */ @Override protected void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { } }