Android-自定义控件之ListView下拉刷新的实现

自定义控件学了很久了,发现学了总是忘,于是打算用博客来记录自己学习的知识点。

今天是自定义ListView来实现下拉刷新,这些文章都是借鉴慕课网上的视频来写的.

自定义一个控件,先是看它继承于那个控件,如果我们继承View控件的话,那得让我们写很多关于ListView的功能,这些东西我自己觉得很麻烦,而且也没有那个必要因为我们可以直接继承ListView,在listView的基础上来加一些我们需要的东西。

1.向ListView加Header布局

private void initView(Context context)

{

mLayoutInflater = LayoutInflater.from(context);

mHeaerView = mLayoutInflater.inflate(R.layout.header_layout, null, false);

addHeaderView(mHeaerView);

}

2.隐藏Header布局

private void initView(Context context) {

mLayoutInflater = LayoutInflater.from(context);

mHeaerView = mLayoutInflater.inflate(R.layout.header_layout, null, false);

measureView(mHeaerView);

mHeaderViewHeight = mHeaerView.getMeasuredHeight();

setHeaderViewHeightPadding(mHeaderViewHeight);

Log.i("main", mHeaderViewHeight + "");

addHeaderView(mHeaerView);

}

private void measureView(View view)

{

ViewGroup.LayoutParams lp = view.getLayoutParams();

if(lp == null)

{

lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

}

//mHeaerView.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

/**

* width 和height里面包含的不仅仅有View的宽和高,还有View控件的测量模式

* 测量模式的产生方式就是如下所示

*/

int width = ViewGroup.getChildMeasureSpec(0,0,lp.width);

int height = 0;

int tempHeight = lp.height;

if(tempHeight > 0)

{

height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY);

}

view.measure(width, height);

}

private void setHeaderViewHeightPadding(int padding) {

mHeaerView.setPadding(mHeaerView.getPaddingLeft(), -padding, mHeaerView.getPaddingRight(), mHeaerView.getPaddingBottom());

mHeaerView.invalidate();

}

3.实现ListView的下拉刷新(一)

要想实现ListView的下拉刷新,必须监听ListView是否滑动到最顶端,因此要实现ListView的监听接口OnScrollListener,并且要监听ListView的OnTouch事件。根据滑动的情况来判断刷新的情况。

首先我们在定义了一个成员变量来保存ListView的状态--mState

其次定义了几个静态常量来表示不同的状态  

private final static int NONE = 0; // 无状态

private final static int DOWN_UPDATE = 1; // 提示下拉可以刷新

private final static int UPDATE = 2; // 提示松开可以刷新

private final static int REFLASH = 3; // 更新

最后则是根据不同的滑动来更改mState的状态

@Override

public boolean onTouchEvent(MotionEvent ev) {

switch (ev.getAction()) {

case MotionEvent.ACTION_DOWN: {

if (mFirstVisibleItem == 0) {

mIsRemark = true; // mIsRemark只是一个标记,表示当前可见的第一个Item是不是所有的Item中的第一个

mStartY = (int) ev.getY();

Log.i("main", "我进来了");

}

break;

}

case MotionEvent.ACTION_MOVE: {

onMove(ev);

tempY = (int) (ev.getY() - mStartY);

Log.i("main", "tempY = " + tempY);

break;

}

case MotionEvent.ACTION_UP: {

if(mState == DOWN_UPDATE)

{

mState = NONE;

}

if(mState == UPDATE)

{

mState = REFLASH;

mListener.reFlash();

Log.i("main", "我来了");

}

Log.i("main", "tempY11 = " + tempY);

if(tempY <= 0 && mIsRemark)

{

Log.i("main", "我进来le");

mState = NONE;

}

change();

break;

}

}

return super.onTouchEvent(ev);

}

private void onMove(MotionEvent ev) {

if (mIsRemark) {

if (ev.getY() - mStartY > 0) {

int dy = (int) (ev.getY() - mStartY);

if (dy > mHeaderViewHeight + 20) {

mState = UPDATE;

} else {

mState = DOWN_UPDATE;

}

setHeaderViewHeightPadding(mHeaderViewHeight - dy);

change();

}

return;

}

return;

}

/**

*change方法主要是用来处理不同状态下的事件

*

*/

private void change() {

initChildView();

RotateAnimation ani = new RotateAnimation(0, 180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);

ani.setDuration(500);

ani.setFillAfter(true);

RotateAnimation ani1 = new RotateAnimation(180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);

ani1.setDuration(500);

ani1.setFillAfter(true);

if (mState == UPDATE)

{

mProgressBar.setVisibility(View.GONE);

mImageView.setVisibility(View.VISIBLE);

mImageView.clearAnimation();

mImageView.setAnimation(ani);

mTextViewFlash.setText("松开可以刷新!");

mTextViewTime.setVisibility(View.VISIBLE);

mTextViewTime.setText("上次更新的时间:" + mUpdateTime);

}

if (mState == DOWN_UPDATE)

{

mProgressBar.setVisibility(View.GONE);

mImageView.setVisibility(View.VISIBLE);

mTextViewTime.setVisibility(View.VISIBLE);

mImageView.clearAnimation();

mImageView.setAnimation(ani1);

mTextViewFlash.setText("下拉可以刷新");

mTextViewTime.setText("上次更新的时间:" + mUpdateTime);

}

if (mState == REFLASH)

{

setHeaderViewHeightPadding(10);

mProgressBar.setVisibility(View.VISIBLE);

mImageView.setVisibility(View.GONE);

mTextViewTime.setVisibility(View.GONE);

mTextViewFlash.setText("正在刷新...");

mImageView.clearAnimation();

}

if(mState == NONE)

{

Log.i("main", "workspace");

setHeaderViewHeightPadding(mHeaderViewHeight);

mIsRemark = false;

mProgressBar.setVisibility(View.GONE);

mImageView.setVisibility(View.VISIBLE);

mImageView.setAnimation(ani1);

}

}

private void initChildView()

{

if(mTextViewFlash == null)

{

mTextViewFlash = (TextView) mHeaerView.findViewById(R.id.id_textView_Flash);

}

if(mTextViewTime == null)

{

mTextViewTime = (TextView) mHeaerView.findViewById(R.id.id_textView_Time);

}

if(mImageView == null)

{

mImageView = (ImageView) mHeaerView.findViewById(R.id.id_imagView);

}

if(mProgressBar == null)

{

mProgressBar = (ProgressBar) mHeaerView.findViewById(R.id.id_progressbar);

}

}

4.实现ListView的下拉刷新(二)

 经过上面的过程,是可以下拉的,处理不同状态下的事件。还有一个问题就是刷新,也就是加载新的数据。加载刷新的操作肯定必须在UI线程中,因此ListView中必须得有一个回调接口,用来MinaActivity来实现,并且来进行一些操作。

  回调接口:

public void setOnFlashListener(FlashListener listener)

{

this.mListener = listener;

}

public interface FlashListener

{

void reFlash();

}

回调接口的调用:

if(mState == UPDATE)

{

mState = REFLASH;

mListener.reFlash();

Log.i("main", "我来了");

}

MainActivity中回调接口的实现和接口方法的实现:

mListView.setOnFlashListener(new FlashListView.FlashListener() {

@Override

public void reFlash() {

Handler handler = new Handler();

handler.postDelayed(new Runnable() {

@Override

public void run() {

addDatas();

loadDatas();

mListView.reFalshComplete();

}

}, 5000);

}

});

  

private void addDatas()

{

int i = mDatas.size();

for(int j = i; j < i + 10; j++)

{

mDatas.add(new Bean("Title" + j, "Content" + j, R.mipmap.ic_launcher));

}

myAdapter.dataChange(mDatas);

}

private void loadDatas()

{

mListView.setAdapter(myAdapter);

}

以上是 Android-自定义控件之ListView下拉刷新的实现 的全部内容, 来源链接: utcz.com/z/360154.html

回到顶部