android 自定义ListView实现下拉刷新、分页加载、点击事件——自定义控件学习(七)
2016-09-27 17:02
886 查看
android 自定义ListView实现下拉刷新、分页加载、点击事件——自定义控件学习(七)
本文主要实现的是封装好的ListView,这个ListView实现了下拉刷新、分页加载和点击事件。使用方法如下:1、引入控件的java文件:
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); } } } }
2、在布局文件中增加此控件
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.administrator.customerpulldownrefreshandpageload.MainActivity"> <com.example.administrator.customerpulldownrefreshandpageload.CustomerListViewPullDownRefreshAndPageLoad android:layout_width="match_parent" android:background="@android:color/holo_blue_dark" android:id="@+id/customListView" android:layout_height="match_parent"></com.example.administrator.customerpulldownrefreshandpageload.CustomerListViewPullDownRefreshAndPageLoad> </RelativeLayout>
3、引入必要的资源:
progressbar.xml==>参考文章:android 使用代码方式创建自定义progressBar——自定义控件学习(六)
<?xml version="1.0" encoding="utf-8"?> <animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="0" android:toDegrees="360"> <shape android:shape="ring" android:innerRadiusRatio="3" android:thicknessRatio="8" android:useLevel="false"> <gradient android:type="sweep" android:useLevel="false" android:startColor="#EEEEEE" android:centerColor="#CCCCCC" android:centerY="0.50" android:endColor="#AAAAAA" /> </shape> </animated-rotate>
simple_list.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/colorAccent" android:textSize="50sp" android:id="@+id/simple_list_textview"/> </LinearLayout>
4、在MainActivity.java中设置控件,并且实现接口CustomerListViewPullDownRefreshAndPageLoad.refreshEvent。
package com.example.administrator.customerpulldownrefreshandpageload; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Toast; import java.util.ArrayList; import java.util.List; import java.util.Random; public class MainActivity extends AppCompatActivity implements CustomerListViewPullDownRefreshAndPageLoad.refreshEvent { private final String TAG = MainActivity.class.getSimpleName(); private CustomerListViewPullDownRefreshAndPageLoad customerListViewPullDownRefreshAndPageLoad; private List<String> data; private ArrayAdapter<String> adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); customerListViewPullDownRefreshAndPageLoad = (CustomerListViewPullDownRefreshAndPageLoad) this.findViewById(R.id.customListView); data = new ArrayList<String>(); for (int i = 0; i < 30; i++) { data.add("测试数据" + i); } adapter = new ArrayAdapter<String>(this, R.layout.simple_list, R.id.simple_list_textview, data); customerListViewPullDownRefreshAndPageLoad.setAdapter(adapter); customerListViewPullDownRefreshAndPageLoad.setRefreshEvent(this); } @Override public void refresh() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } data.clear(); Random random = new Random(); for (int i = 0; i < 30; i++) { data.add("测试数据" + String.valueOf(random.nextInt(100) + 1)); } } @Override public void loadMore(int startIndex, int endIndex) { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } data.addAll(getDataService(startIndex,endIndex)); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MainActivity.this, "position=" + position + " id=" + id, Toast.LENGTH_SHORT).show(); } /** * 模拟加载数据 * * @param from * @param to * @return */ public List<String> getDataService(int from, int to) { Log.i(TAG,"----start " + from + " end" + to); List<String> resList = new ArrayList<>(); for (int i = from; i < to; i++) { resList.add("测试数据" + i); } return resList; } @Override protected void onDestroy() { customerListViewPullDownRefreshAndPageLoad.tempThreadRefresh = null; customerListViewPullDownRefreshAndPageLoad.tempThreadLoadMore = null; super.onDestroy(); } }
5、运行效果:
下拉刷新:
分页加载:
点击事件:
最后,附上代码:点我下载,不要你的积分哦!!!
相关文章推荐
- Android自定义控件(二) 下拉刷新,上拉分页加载更多(支持ListView, GridView, ScrollView)
- android ListView的上部下拉刷新下部点击加载更多具体实现及拓展
- 自定义ListView实现下拉刷新和分页加载(效果类似知乎)
- Android自定义ListView实现分页加载
- Android 自定义ListView 实现下拉刷新 上拉加载功能
- 2014-10-27Android学习------布局处理(八)------自定义ListView的监听事件和Adapter的实现-----城市列表应用程序
- Android UI--自定义ListView(实现下拉刷新+加载更多)
- Android使用RecyclerView实现自定义列表、点击事件以及下拉刷新
- Android实现RecyclerView自定义列表、点击事件以及下拉刷新
- Android UI--自定义ListView(实现下拉刷新+加载更多)
- Android UI--自定义ListView(实现下拉刷新+加载更多)
- Android UI--自定义ListView(实现下拉刷新+加载更多)
- Android中自定义ListView实现上拉加载更多和下拉刷新
- android ListView的上部下拉刷新下部点击加载更多具体实现及拓展
- Android UI--自定义ListView(实现下拉刷新+加载更多)
- Android 自定义ListView实现底部分页刷新与顶部下拉刷新
- Android自定义控件(一) 下拉刷新,上拉分页加载更多(支持ListView, GridView, ScrollView)
- android ListView的上部下拉刷新下部点击加载更多具体实现及拓展
- android 自定义ListView下拉刷新控件——自定义控件学习(五)
- Android自定义View之快速实现下拉刷新, 点击加载更多ListView