android 自定義ListView實現下拉重新整理、分頁載入、點選事件——自定義控制元件學習(七)
阿新 • • 發佈:2019-01-25
package com.example.administrator.customerpulldownrefreshandpageload; import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; /** * Created by Administrator on 2016-09-27. */ public class CustomerListViewPullDownRefreshAndPageLoad extends RelativeLayout { private final String TAG = CustomerListViewPullDownRefreshAndPageLoad.class.getSimpleName(); private final int REFRESHMSG_CODE = 0x994; private final int LOADMORE_CODE = 0x887; private ListView listView; private LinearLayout footer; private ArrayAdapter<String> adapter; private ViewGroup.MarginLayoutParams marginLayoutParams; private ViewGroup.MarginLayoutParams marginLayoutParamspro; //上方的存放圖示和文字的LinearLayout private LinearLayout linearLayout; //在上方存檔的內容包括以下的imageView progressBar textView private ImageView imageArrow; private ProgressBar progressBar; private TextView textViewTip; private final int MARGIN_TOP = -200; private final int IMAGE_SIZE = 50; private boolean pullFlag; private boolean returnFlag; //重新整理完成標誌 private boolean refreshFinishFlag; private int oldY; private int newY; private int distance; //執行緒 public Thread tempThreadRefresh; //介面 public interface refreshEvent { //下拉重新整理 void refresh(); //分頁載入 void loadMore(int startIndex, int endIndex); //item點選 void onItemClick(AdapterView<?> parent, View view, int position, long id); } private refreshEvent refreshEvent; //分頁載入 private boolean loadFinishFlag; private ProgressBar progressBarFooter; private TextView textViewTipFooter; private int startIndex; private int endIndex; private final int pageSize = 20; //執行緒 public Thread tempThreadLoadMore; public CustomerListViewPullDownRefreshAndPageLoad(Context context, AttributeSet attrs) { super(context, attrs); listView = new ListView(getContext()); RelativeLayout.LayoutParams reLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); reLayoutParams.setMargins(0, 0, 0, 0); listView.setLayoutParams(reLayoutParams); listView.setBackgroundColor(getResources().getColor(android.R.color.white)); addView(listView); linearLayout = new LinearLayout(getContext()); RelativeLayout.LayoutParams liLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); liLayoutParams.setMargins(0, MARGIN_TOP, 0, 0); linearLayout.setOrientation(LinearLayout.HORIZONTAL); linearLayout.setGravity(Gravity.CENTER); linearLayout.setLayoutParams(liLayoutParams); addView(linearLayout); imageArrow = new ImageView(getContext()); imageArrow.setImageResource(R.drawable.arrowdown); LinearLayout.LayoutParams imgLayoutParams = new LinearLayout.LayoutParams(IMAGE_SIZE, IMAGE_SIZE); imageArrow.setLayoutParams(imgLayoutParams); linearLayout.addView(imageArrow); progressBar = new ProgressBar(getContext()); LinearLayout.LayoutParams proLayoutParams = new LinearLayout.LayoutParams(IMAGE_SIZE, IMAGE_SIZE); progressBar.setIndeterminateDrawable(getResources().getDrawable(R.drawable.progressbar)); progressBar.setLayoutParams(proLayoutParams); linearLayout.addView(progressBar); textViewTip = new TextView(getContext()); LinearLayout.LayoutParams texLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); texLayoutParams.setMargins(20, 0, 0, 0); textViewTip.setText("正在重新整理..."); textViewTip.setLayoutParams(texLayoutParams); linearLayout.addView(textViewTip); pullFlag = false; returnFlag = false; refreshFinishFlag = true; loadFinishFlag = true; oldY = 0; newY = 0; distance = 0; startIndex = 0; endIndex = pageSize; marginLayoutParams = (ViewGroup.MarginLayoutParams) listView.getLayoutParams(); marginLayoutParamspro = (ViewGroup.MarginLayoutParams) linearLayout.getLayoutParams(); //設定滑動事件 listView.setOnTouchListener(new MyOnTouch()); footer = new LinearLayout(getContext()); footer.setGravity(Gravity.CENTER); progressBarFooter = new ProgressBar(getContext()); LinearLayout.LayoutParams footerProLayoutParams = new LinearLayout.LayoutParams(IMAGE_SIZE, IMAGE_SIZE); progressBarFooter.setIndeterminateDrawable(getResources().getDrawable(R.drawable.progressbar)); progressBarFooter.setLayoutParams(footerProLayoutParams); footer.addView(progressBarFooter); textViewTipFooter = new TextView(getContext()); LinearLayout.LayoutParams footerTexLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); footerTexLayoutParams.setMargins(20, 0, 0, 0); textViewTipFooter.setText("正在載入..."); textViewTipFooter.setLayoutParams(footerTexLayoutParams); footer.addView(textViewTipFooter); //設定分頁載入 listView.setOnScrollListener(new ScrollListener()); //這是點選事件 listView.setOnItemClickListener(new MyItemClick()); } //滑動事件 class MyOnTouch implements View.OnTouchListener { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: View firstChild = listView.getChildAt(0); if (firstChild != null) { //當前第一個是第幾項 int firstChildPosition = listView.getFirstVisiblePosition(); //第一項的座標為0 int firstChildTop = firstChild.getTop(); if (firstChildPosition == 0 && firstChildTop == 0 && refreshFinishFlag && loadFinishFlag) { pullFlag = true; Log.i(TAG, "---->ACTION_DOWN" + String.valueOf(pullFlag)); } Log.i(TAG, "---->ACTION_DOWN" + String.valueOf(firstChildPosition)); Log.i(TAG, "---->ACTION_DOWN" + String.valueOf(firstChildTop)); } returnFlag = false; Log.i(TAG, "---->ACTION_DOWN"); oldY = (int) event.getRawY(); distance = 0; break; case MotionEvent.ACTION_MOVE: newY = (int) event.getRawY(); distance = newY - oldY; if (pullFlag && distance > 0) { returnFlag = true; marginLayoutParams.topMargin = distance / 2; listView.setLayoutParams(marginLayoutParams); if (distance < 300) { //正在下拉 downStatus(); marginLayoutParamspro.topMargin = (distance / 2) - 100; linearLayout.setLayoutParams(marginLayoutParamspro); //防止強迫症,拉完有放回來 refreshFinishFlag = true; } else { //下拉大於150,能夠執行重新整理動作 //更新標誌位,為完成下拉 refreshFinishFlag = false; //顯示釋放 upStatus(); } } break; case MotionEvent.ACTION_UP: Log.i(TAG, "---->ACTION_UP"); if (pullFlag) { if (distance < 300) { //下拉沒有到位釋放 marginLayoutParams.topMargin = 0; //隱藏上邊的部分 marginLayoutParamspro.topMargin = MARGIN_TOP; linearLayout.setLayoutParams(marginLayoutParamspro); } else { marginLayoutParams.topMargin = 150; //防止快速點拉 marginLayoutParamspro.topMargin = 50; linearLayout.setLayoutParams(marginLayoutParamspro); //顯示正在重新整理 refreshingStatus(); //下拉到位釋放,啟動重新整理執行緒 tempThreadRefresh = new Thread() { @Override public void run() { super.run(); //插入重新整理事件 refreshEvent.refresh(); handler.obtainMessage(REFRESHMSG_CODE).sendToTarget(); } }; tempThreadRefresh.start(); } listView.setLayoutParams(marginLayoutParams); } pullFlag = false; returnFlag = false; break; } //true時listview不能進行滑動,false時能夠進行滑動 return returnFlag; } } public void downStatus() { imageArrow.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); imageArrow.setImageResource(R.drawable.arrowdown); textViewTip.setText("下拉重新整理..."); } public void upStatus() { imageArrow.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); imageArrow.setImageResource(R.drawable.arrowup); textViewTip.setText("釋放重新整理..."); } public void refreshingStatus() { imageArrow.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); textViewTip.setText("正在重新整理..."); } public void setAdapter(ArrayAdapter<String> adapter) { this.adapter = adapter; listView.setAdapter(adapter); } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case REFRESHMSG_CODE: //通知下拉重新整理 adapter.notifyDataSetChanged(); Toast.makeText(getContext(), "重新整理完成", Toast.LENGTH_SHORT).show(); refreshFinishFlag = true; //隱藏上邊的部分 marginLayoutParamspro.topMargin = MARGIN_TOP; linearLayout.setLayoutParams(marginLayoutParamspro); //ListView回到原位 marginLayoutParams.topMargin = 0; listView.setLayoutParams(marginLayoutParams); //重新整理後,下拉載入重新開始 startIndex = 0; endIndex = pageSize; break; case LOADMORE_CODE: //通知載入更多 adapter.notifyDataSetChanged(); listView.removeFooterView(footer); loadFinishFlag = true; break; } } }; public void setRefreshEvent(CustomerListViewPullDownRefreshAndPageLoad.refreshEvent refreshEvent) { this.refreshEvent = refreshEvent; } public final class ScrollListener implements AbsListView.OnScrollListener { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { Log.i(TAG, "---->" + scrollState); switch (scrollState) { case SCROLL_STATE_IDLE: break; case SCROLL_STATE_TOUCH_SCROLL: break; case SCROLL_STATE_FLING: break; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //獲取螢幕最後Item的ID int lastVisibleItem = listView.getLastVisiblePosition(); if (lastVisibleItem + 1 == totalItemCount) { if (loadFinishFlag && refreshFinishFlag) { //標誌位,防止多次載入 loadFinishFlag = false; listView.addFooterView(footer); //開執行緒載入資料 tempThreadLoadMore = new Thread() { @Override public void run() { super.run(); startIndex += pageSize; endIndex += pageSize; //分頁載入 if (refreshEvent != null) { refreshEvent.loadMore(startIndex, endIndex); } Message message = handler.obtainMessage(LOADMORE_CODE); message.sendToTarget(); } }; tempThreadLoadMore.start(); } } } } class MyItemClick implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if(refreshFinishFlag&& loadFinishFlag){ refreshEvent.onItemClick(parent, view, position, id); } } } }