android 개발 중ListView의 묘용: 밑에 있는 리셋과 끝까지 더 많은 원본 불러오기
37758 단어 android
먼저 ListView는 새로 고침된 인터페이스가 없다는 것을 알았습니다. 기존의 기능을 빌려 더 많은 기능을 확장하려면 ListView가 우리의 요구를 충족시킬 수 있도록 수정해야 합니다.
1. ListView의 표면적인 이해는 List의 형식으로 표시된 View이다. 즉, 한 줄 한 줄 표시를 하려면 ListView에 어댑터를 추가하는 것이 없어서는 안 된다.그래서 우리가 수정한 ListView는 당연히 어댑터 등 흔히 볼 수 있는 ListView에 대한 조작을 추가할 수 있다.
2. 우리가 목록 인터페이스에 대한 조작을 포착하려면 아래로 내려가거나 끝까지 스크롤하려면 사건에 대한 감청기가 있어야 한다. 여기서 특히 중요하다. 우리는 단추에 감청기를 추가하는 것을 알고 있다. 우리는 우리가 어떤 단추에 조작을 한 것을 포착하고 우리의 조작을 수행할 수 있다. 여기서 아래로 내려가거나 끝까지 스크롤할 수 있다.우리도 당연히 이 동작을 포착하고 우리가 실행하고자 하는 동작을 실행해야 한다.
3. 원리는 우리가 알고 있다. 이제 이 동작을 어떻게 포획하는지, 그리고 포획 동작을 포획한 후에 우리가 원하는 조작을 어떻게 추가하는지.동작만 잡으면 네가 무엇을 하고 싶은지 나는 관심이 없다. 왜냐하면 수요가 각양각색이기 때문이다.
4. 동작을 포착한 후에 우리는 사용자에게 반응을 보이기 시작한다...
다음은 이 데모의 코드를 살펴보겠습니다.
package com.example.pulldownview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ListView;
/**
* <p> ListView </p>
* , ListView Flying , </br>
* , scroll
* @author solo ho</br> Email:[email protected]
*/
public class ScrollOverListView extends ListView {
private static final String TAG = "ScrollOverListView";
private static final boolean DEBUG = false;
private int mLastY;
private int mTopPosition;
private int mBottomPosition;
public ScrollOverListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public ScrollOverListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ScrollOverListView(Context context) {
super(context);
init();
}
private void init(){
mTopPosition = 0;
mBottomPosition = 0;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
if (DEBUG) Log.d(TAG, "onInterceptTouchEvent Action down");
mLastY = (int) ev.getRawY();
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
final int y = (int) ev.getRawY();
boolean isHandled = false;
switch(action){
case MotionEvent.ACTION_DOWN:{
if (DEBUG) Log.d(TAG, "action down");
mLastY = y;
isHandled = mOnScrollOverListener.onMotionDown(ev);
if (isHandled) {
break;
}
break;
}
case MotionEvent.ACTION_MOVE:{
if (DEBUG) Log.d(TAG, "action move");
final int childCount = getChildCount();
if(childCount == 0) {
break;
}
final int itemCount = getAdapter().getCount() - mBottomPosition;
final int deltaY = y - mLastY;
if (DEBUG) Log.d(TAG, "lastY=" + mLastY +" y=" + y);
final int firstTop = getChildAt(0).getTop();
final int listPadding = getListPaddingTop();
final int lastBottom = getChildAt(childCount - 1).getBottom();
final int end = getHeight() - getPaddingBottom();
final int firstVisiblePosition = getFirstVisiblePosition();
isHandled = mOnScrollOverListener.onMotionMove(ev, deltaY);
if(isHandled){
break;
}
//DLog.d("firstVisiblePosition=%d firstTop=%d listPaddingTop=%d deltaY=%d", firstVisiblePosition, firstTop, listPadding, deltaY);
if (firstVisiblePosition <= mTopPosition && firstTop >= listPadding && deltaY > 0) {
if (DEBUG) Log.d(TAG, "action move pull down");
isHandled = mOnScrollOverListener.onListViewTopAndPullDown(ev, deltaY);
if(isHandled){
break;
}
}
// DLog.d("lastBottom=%d end=%d deltaY=%d", lastBottom, end, deltaY);
if (firstVisiblePosition + childCount >= itemCount && lastBottom <= end && deltaY < 0) {
if (DEBUG) Log.d(TAG, "action move pull up");
isHandled = mOnScrollOverListener.onListViewBottomAndPullUp(ev, deltaY);
if(isHandled){
break;
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:{
if (DEBUG) Log.d(TAG, "action move pull up");
isHandled = mOnScrollOverListener.onMotionUp(ev);
if (isHandled) {
break;
}
break;
}
}
mLastY = y;
if (isHandled) {
return true;
}
return super.onTouchEvent(ev);
}
/** */
private OnScrollOverListener mOnScrollOverListener = new OnScrollOverListener(){
@Override
public boolean onListViewTopAndPullDown(MotionEvent event, int delta) {
return false;
}
@Override
public boolean onListViewBottomAndPullUp(MotionEvent event, int delta) {
return false;
}
@Override
public boolean onMotionDown(MotionEvent ev) {
return false;
}
@Override
public boolean onMotionMove(MotionEvent ev, int delta) {
return false;
}
@Override
public boolean onMotionUp(MotionEvent ev) {
return false;
}
};
// =============================== public method ===============================
/**
* , ,
*
* @param index ,
*/
public void setTopPosition(int index){
if(index < 0)
throw new IllegalArgumentException("Top position must > 0");
mTopPosition = index;
}
/**
* , ,
*
* @param index ,
*/
public void setBottomPosition(int index){
if(index < 0)
throw new IllegalArgumentException("Bottom position must > 0");
mBottomPosition = index;
}
/**
* Listener , </br>
*
* @see OnScrollOverListener
*/
public void setOnScrollOverListener(OnScrollOverListener onScrollOverListener){
mOnScrollOverListener = onScrollOverListener;
}
/**
* </br>
* @see ScrollOverListView#setOnScrollOverListener(OnScrollOverListener)
*
* @author solo ho</br> Email:[email protected]
*/
public interface OnScrollOverListener {
/**
*
*
* @param delta
* @return
*/
boolean onListViewTopAndPullDown(MotionEvent event, int delta);
/**
*
*
* @param delta
* @return
*/
boolean onListViewBottomAndPullUp(MotionEvent event, int delta);
/**
* , {@link MotionEvent#ACTION_DOWN}
*
* @return true
* @see View#onTouchEvent(MotionEvent)
*/
boolean onMotionDown(MotionEvent ev);
/**
* , {@link MotionEvent#ACTION_MOVE}
*
* @return true
* @see View#onTouchEvent(MotionEvent)
*/
boolean onMotionMove(MotionEvent ev, int delta);
/**
* , {@link MotionEvent#ACTION_UP}
*
* @return true
* @see View#onTouchEvent(MotionEvent)
*/
boolean onMotionUp(MotionEvent ev);
}
}
2. 내려와서 리셋
package com.example.pulldownview;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.pulldownview.ScrollOverListView.OnScrollOverListener;
/**
* </br>
* ,
* ScrollOverListView
* @author Solo Email:[email protected]
*/
public class PullDownView extends LinearLayout implements OnScrollOverListener, OnScrollListener {
private static final String TAG = "PullDownView";
private static final boolean DEBUG = false;
private static final int AUTO_INCREMENTAL = 10; // ,
private static final int WHAT_SET_HEADER_HEIGHT = 1;// Handler what
private static SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm");
private View mHeaderView;
private LayoutParams mHeaderViewParams;
private TextView mHeaderViewDateView;
private TextView mHeaderTextView;
private ImageView mHeaderArrowView;
private View mHeaderLoadingView;
private View mFooterView;
private TextView mFooterTextView;
private View mFooterLoadingView;
private ScrollOverListView mListView;
private OnPullDownListener mOnPullDownListener;
private RotateAnimation mRotateOTo180Animation;
private RotateAnimation mRotate180To0Animation;
private Context mContext;
private Field overScrollModeField;
private int mMoveDeviation; //
private int mHeaderIncremental; //
private int mDefaultHeaderViewHeight; //
private int mStartIndex; // List
//private int mEndIndex; // List
private float mMotionDownLastY; // Y
private boolean mEnablePullDown; //
private boolean mIsPullUpDone; //
private boolean mEnableLoadMore; //
private boolean mEnableAutoFetchMore; //
private boolean mIsNoMoreData; //
private boolean mIsDidLoad; //
//
private static final int HEADER_VIEW_STATE_IDLE = 0; //
private static final int HEADER_VIEW_STATE_NOT_OVER_HEIGHT = 1; //
private static final int HEADER_VIEW_STATE_OVER_HEIGHT = 2; //
private int mHeaderViewState = HEADER_VIEW_STATE_IDLE;
private static final int STATE_NONE = 0;
private static final int STATE_REFRESHING = 1; //
private static final int STATE_LOADING_MORE = 2; //
private static final int STATE_DRAGING = 4; //
private static final int STATE_MOTION_DOWN = 8; //
private int state = STATE_NONE;
public PullDownView(Context context, AttributeSet attrs) {
super(context, attrs);
initHeaderViewAndFooterViewAndListView(context);
}
public PullDownView(Context context) {
super(context);
initHeaderViewAndFooterViewAndListView(context);
}
/*
* ==================================
* Public method
* ,
*
* ==================================
*/
/**
*
* @author Solo Email:[email protected]
*/
public interface OnPullDownListener {
void onRefresh();
void onLoadMore();
}
/**
* , Adapter.notifyDataSetChanged
* , notifyDidLoad()
* ,
*/
public void notifyDidDataLoad(boolean isNoMoreData) {
mIsDidLoad = true;
mIsNoMoreData = isNoMoreData;
mFooterView.setVisibility(View.VISIBLE);
updateFooter();
mListView.setFooterDividersEnabled(true);
mHeaderViewParams.height = 0;
mHeaderView.setLayoutParams(mHeaderViewParams);
updateHeader();
doListViewIdleActionOnDataDidLoad();
}
/**
* , Adapter.notifyDataSetChanged
* , notifyDidRefresh()
*
*/
public void notifyDidRefresh(boolean isNoMoreData) {
mIsNoMoreData = isNoMoreData;
updateFooter();
state &= ~STATE_REFRESHING;
mHeaderViewState = HEADER_VIEW_STATE_IDLE;
setHeaderHeight(0);
updateHeader();
doListViewIdleActionOnDataDidLoad();
}
/**
* , Adapter.notifyDataSetChanged
* , notyfyDidMore()
*
*/
public void notifyDidLoadMore(boolean isNoMoreData) {
mIsNoMoreData = isNoMoreData;
state &= ~STATE_LOADING_MORE;
updateFooter();
}
/**
*
* @param listener
*/
public void setOnPullDownListener(OnPullDownListener listener){
mOnPullDownListener = listener;
}
/**
* listview
* @return ScrollOverListView
*/
public ScrollOverListView getListView(){
return mListView;
}
/**
* </br>
* ,
* @param index
*/
public void enableAutoFetchMore(boolean enable, int index){
if(!mEnableLoadMore) return;
mEnableAutoFetchMore = enable;
if(enable){
mListView.setBottomPosition(index);
}else{
updateFooter();
}
}
/**
* </br>
*
*/
public void enableLoadMore(boolean enable) {
mEnableLoadMore = enable;
if (!enable) {
// TODO
//
mUIHandler.post(new Runnable() {
@Override
public void run() {
removeFooter();
}
});
}
}
/**
*
*/
public void enablePullDown(boolean enable) {
mEnablePullDown = enable;
}
/*
* ==================================
* Private method
*
*
* ==================================
*/
/**
*
*/
private void initHeaderViewAndFooterViewAndListView(Context context){
setOrientation(LinearLayout.VERTICAL);
mContext = context;
/*
*
*
* ,
*/
mEnablePullDown = true;
mHeaderView = LayoutInflater.from(context).inflate(R.layout.pulldown_header, null);
mHeaderViewParams = new LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
mHeaderIncremental = mDefaultHeaderViewHeight;
addView(mHeaderView, 0, mHeaderViewParams);
mDefaultHeaderViewHeight = getResources().getDimensionPixelSize(R.dimen.pulldown_headerview_height);
mMoveDeviation = getResources().getDimensionPixelSize(R.dimen.pulldown_move_deviation);
mHeaderTextView = (TextView) mHeaderView.findViewById(R.id.pulldown_header_text);
mHeaderArrowView = (ImageView) mHeaderView.findViewById(R.id.pulldown_header_arrow);
mHeaderViewDateView = (TextView) mHeaderView.findViewById(R.id.pulldown_header_date);
mHeaderLoadingView = mHeaderView.findViewById(R.id.pulldown_header_loading);
// , , ,
mRotateOTo180Animation = new RotateAnimation(0, 180,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
mRotateOTo180Animation.setDuration(250);
mRotateOTo180Animation.setFillAfter(true);
mRotate180To0Animation = new RotateAnimation(180, 0,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
mRotate180To0Animation.setDuration(250);
mRotate180To0Animation.setFillAfter(true);
/*
*
*/
mEnableLoadMore = true;
mFooterView = LayoutInflater.from(mContext).inflate(R.layout.pulldown_footer, null);
mFooterView.setVisibility(View.GONE);
mFooterTextView = (TextView) mFooterView.findViewById(R.id.pulldown_footer_text);
mFooterLoadingView = mFooterView.findViewById(R.id.pulldown_footer_loading);
mFooterView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mIsNoMoreData || !mIsDidLoad || (state & STATE_LOADING_MORE) == STATE_LOADING_MORE) return;
ScrollOverListView listView = mListView;
if (listView.getCount() - listView.getHeaderViewsCount() - listView.getFooterViewsCount() > 0) {
state |= STATE_LOADING_MORE;
updateFooter();
mOnPullDownListener.onLoadMore();
}
}
});
/*
* ScrollOverListView ,
* ,
*/
mListView = new ScrollOverListView(context);
mListView.setFooterDividersEnabled(false);
mListView.setId(android.R.id.list);
mListView.addFooterView(mFooterView);
mListView.setOnScrollOverListener(this);
mListView.setOnScrollListener(this);
// 2.3 ListView pull
//
try {
Method method = AbsListView.class.getDeclaredMethod("setOverScrollMode", int.class);
method.setAccessible(true);
method.invoke(mListView, 2);//View.OVER_SCROLL_NEVER
} catch (Exception e) {
e.printStackTrace();
}
addView(mListView, android.view.ViewGroup.LayoutParams.FILL_PARENT, android.view.ViewGroup.LayoutParams.FILL_PARENT);
// set ListView animation
/*
AnimationSet set = new AnimationSet(true);
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(50);
set.addAnimation(animation);
animation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f,Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -1.0f,Animation.RELATIVE_TO_SELF, 0.0f
);
animation.setDuration(100);
set.addAnimation(animation);
LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f);
mListView.setLayoutAnimation(controller);
*/
// listener
mOnPullDownListener = new OnPullDownListener() {
@Override
public void onRefresh() {}
@Override
public void onLoadMore() {}
};
}
/**
*
*/
private void removeFooter(){
if(mListView.getFooterViewsCount() > 0 && mListView != null && mFooterView != null){
mListView.removeFooterView(mFooterView);
}
}
/**
* </br>
* Loading,
* , ,
* 。
*/
private void updateHeader() {
if ((state & STATE_REFRESHING) == STATE_REFRESHING) {
mHeaderArrowView.clearAnimation();
mHeaderArrowView.setVisibility(View.GONE);
mHeaderLoadingView.setVisibility(View.VISIBLE);
mHeaderTextView.setText(" ...");
} else if ((state & STATE_DRAGING) == STATE_DRAGING) {
if(mHeaderViewParams.height >= mDefaultHeaderViewHeight){
if(mHeaderViewState == HEADER_VIEW_STATE_OVER_HEIGHT) return;
mHeaderArrowView.setVisibility(View.VISIBLE);
mHeaderLoadingView.setVisibility(View.GONE);
mHeaderViewDateView.setVisibility(View.VISIBLE);
mHeaderViewState = HEADER_VIEW_STATE_OVER_HEIGHT;
mHeaderTextView.setText(" ");
mHeaderArrowView.startAnimation(mRotateOTo180Animation);
}else{
if(mHeaderViewState == HEADER_VIEW_STATE_NOT_OVER_HEIGHT
|| mHeaderViewState == HEADER_VIEW_STATE_IDLE) return;
mHeaderArrowView.setVisibility(View.VISIBLE);
mHeaderLoadingView.setVisibility(View.GONE);
mHeaderViewDateView.setVisibility(View.VISIBLE);
mHeaderViewState = HEADER_VIEW_STATE_NOT_OVER_HEIGHT;
mHeaderTextView.setText(" ");
mHeaderArrowView.startAnimation(mRotate180To0Animation);
}
} else {
mHeaderLoadingView.setVisibility(View.GONE);
mHeaderViewDateView.setVisibility(View.VISIBLE);
mHeaderArrowView.setVisibility(View.VISIBLE);
mHeaderTextView.setText(" ");
mHeaderViewDateView.setText(" :" + dateFormat.format(new Date(System.currentTimeMillis())));
}
}
/**
* </br>
* " ",
* " ",
* " ..."。
*/
private void updateFooter() {
if (!mEnableLoadMore) return;
if (mIsNoMoreData) {
mFooterTextView.setText(" ");
mFooterLoadingView.setVisibility(View.GONE);
} else if ((state & STATE_LOADING_MORE) == STATE_LOADING_MORE) {
mFooterTextView.setText(" ...");
mFooterLoadingView.setVisibility(View.VISIBLE);
} else {
mFooterTextView.setText(" ");
mFooterLoadingView.setVisibility(View.GONE);
}
}
private void setHeaderHeight(final int height){
mHeaderIncremental = height;
mHeaderViewParams.height = height;
mHeaderView.setLayoutParams(mHeaderViewParams);
}
/**
*
*/
class HideHeaderViewTask extends TimerTask{
@Override
public void run() {
if((state & STATE_MOTION_DOWN) == STATE_MOTION_DOWN) {
cancel();
return;
}
mHeaderIncremental -= AUTO_INCREMENTAL;
if(mHeaderIncremental > 0){
mUIHandler.sendEmptyMessage(WHAT_SET_HEADER_HEIGHT);
}else{
mHeaderIncremental = 0;
mUIHandler.sendEmptyMessage(WHAT_SET_HEADER_HEIGHT);
cancel();
}
}
}
/**
*
*/
class ShowHeaderViewTask extends TimerTask{
@Override
public void run() {
if((state & STATE_MOTION_DOWN) == STATE_MOTION_DOWN) {
cancel();
return;
}
mHeaderIncremental -= AUTO_INCREMENTAL;
if(mHeaderIncremental > mDefaultHeaderViewHeight){
mUIHandler.sendEmptyMessage(WHAT_SET_HEADER_HEIGHT);
}else{
mHeaderIncremental = mDefaultHeaderViewHeight;
mUIHandler.sendEmptyMessage(WHAT_SET_HEADER_HEIGHT);
if (mIsDidLoad && (state & STATE_REFRESHING) != STATE_REFRESHING) {
state |= STATE_REFRESHING;
mUIHandler.post(new Runnable() {
@Override
public void run() {
// ,
updateHeader();
mHeaderArrowView.clearAnimation();
mHeaderArrowView.setVisibility(View.INVISIBLE);
mHeaderLoadingView.setVisibility(View.VISIBLE);
mOnPullDownListener.onRefresh();
}
});
}
cancel();
}
}
}
private Handler mUIHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case WHAT_SET_HEADER_HEIGHT :{
setHeaderHeight(mHeaderIncremental);
return;
}
}
}
};
/**
* , onIdle
*/
private void doListViewIdleActionOnDataDidLoad(){
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if(mOnListViewIdleListener != null){
// FooterView
final int firstVisiblePosition = mListView.getFirstVisiblePosition();
final int childCount = mListView.getChildCount();
//Log.d(TAG, "[doListViewIdleActionOnDataDidLoad] firstVisiblePosition:" + firstVisiblePosition + " childCount:" + childCount);
mOnListViewIdleListener.onIdle(firstVisiblePosition, childCount);
}
}
}, 0);
}
/**
*
*/
private boolean isFillScreenItem(){
final int firstVisiblePosition = mListView.getFirstVisiblePosition();
final int lastVisiblePosition = mListView.getLastVisiblePosition() - mListView.getFooterViewsCount();
final int visibleItemCount = lastVisiblePosition - firstVisiblePosition + 1;
final int totalItemCount = mListView.getCount() - mListView.getFooterViewsCount();
if(visibleItemCount < totalItemCount) return true;
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
state |= STATE_MOTION_DOWN;
mIsPullUpDone = false;
mMotionDownLastY = ev.getRawY();
Log.d(TAG, "pulldownview.onIntercept:" + mMotionDownLastY);
}
return super.onInterceptTouchEvent(ev);
}
/*
* ==================================
* OnScrollOverListener
*
*
* ==================================
*/
@Override
public boolean onListViewTopAndPullDown(MotionEvent event, int delta) {
// ListView
// true, ListView ,
if ((state & STATE_REFRESHING) == STATE_REFRESHING || !mEnablePullDown || !mIsDidLoad) {
return true;
}
if (mListView.getCount() - mListView.getFooterViewsCount() == 0) {
return true;
}
// ,
if(mHeaderViewParams.height <= 0){
final int absMotionY = (int) Math.abs(event.getRawY() - mMotionDownLastY);
if(absMotionY < mMoveDeviation) {
return true;
}
}
int absDelta = Math.abs(delta);
final int i = (int) Math.ceil((double)absDelta / 2);
mHeaderIncremental += i;
if(mHeaderIncremental >= 0){ // && mIncremental <= mMaxHeight
setHeaderHeight(mHeaderIncremental);
updateHeader();
}
return true;
}
@Override
public boolean onListViewBottomAndPullUp(MotionEvent event, int delta) {
if((state & STATE_LOADING_MORE) == STATE_LOADING_MORE
|| !mIsDidLoad || !mEnableAutoFetchMore || mIsNoMoreData) return false;
ScrollOverListView listView = mListView;
if (listView.getCount() - listView.getHeaderViewsCount() - listView.getFooterViewsCount() > 0) {
state |= STATE_LOADING_MORE;
updateFooter();
mOnPullDownListener.onLoadMore();
}
return true;
}
@Override
public boolean onMotionDown(MotionEvent ev) {
return false;
}
@Override
public boolean onMotionMove(MotionEvent ev, int delta) {
state |= STATE_DRAGING;
// ,
if(mIsPullUpDone) return true;
// onTopDown , onTopUp
if(mHeaderViewParams.height > 0 && delta < 0){
final int absDelta = Math.abs(delta);
final int i = (int) Math.ceil((double)absDelta / 2);
mHeaderIncremental -= i;
if(mHeaderIncremental > 0){
setHeaderHeight(mHeaderIncremental);
updateHeader();
}else{
mHeaderViewState = HEADER_VIEW_STATE_IDLE;
mHeaderIncremental = 0;
setHeaderHeight(mHeaderIncremental);
mIsPullUpDone = true;
}
return true;
}
return false;
}
@Override
public boolean onMotionUp(MotionEvent ev) {
state &= ~STATE_DRAGING;
state &= ~STATE_MOTION_DOWN;
//
if(mHeaderViewParams.height > 0 || mIsPullUpDone){
// , ,
int x = mHeaderIncremental - mDefaultHeaderViewHeight;
Timer timer = new Timer(true);
if(x < 0){
timer.scheduleAtFixedRate(new HideHeaderViewTask(), 0, 10);
}else{
timer.scheduleAtFixedRate(new ShowHeaderViewTask(), 0, 10);
}
return true;
}
return false;//TODO
}
/*
* =====================================
* ListView
* =====================================
*/
private OnListViewIdleListener mOnListViewIdleListener;
public interface OnListViewIdleListener {
void onIdle(int startIndex, int count);
}
public void setOnListViewIdleListener(OnListViewIdleListener listener){
if(mListView != null){
mOnListViewIdleListener = listener;
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState == SCROLL_STATE_IDLE){
if (DEBUG) Log.d(TAG, "IDLE");
if(mOnListViewIdleListener != null){
int count = mListView.getChildCount();
final int childEndIndex = mStartIndex + mListView.getChildCount() -1;
final int listEndIndex = mListView.getCount() -1;
if(childEndIndex == listEndIndex){
count -= mListView.getFooterViewsCount();
}
mOnListViewIdleListener.onIdle(mStartIndex, count);
}
}
switch (scrollState) {
case SCROLL_STATE_FLING:
if (DEBUG) Log.d(TAG, "FLING");
break;
case SCROLL_STATE_TOUCH_SCROLL:
if (DEBUG) Log.d(TAG, "SCROLL");
default:
break;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (DEBUG) Log.d(TAG, "onScroll");
mStartIndex = firstVisibleItem;
// I91002.3 over_scroll_never ,
// 12-9-9 2:08: , 2.3.3 。
/*
final ScrollOverListView localListView = this.mListView;
final boolean hasItem = localListView.getCount() > 0;
try {
if (overScrollModeField == null) return;
final Integer mode = (Integer) overScrollModeField.get(localListView);
if (firstVisibleItem <= 0 && hasItem) {
if (mode != View.OVER_SCROLL_NEVER) {
if (DEBUG) Log.w(TAG, "set over scroll never");
overScrollModeField.set(localListView, View.OVER_SCROLL_NEVER);
}
} else if (firstVisibleItem + visibleItemCount >= totalItemCount && hasItem) {
if (mode != View.OVER_SCROLL_ALWAYS) {
if (DEBUG) Log.w(TAG, "set over scroll always");
overScrollModeField.set(localListView, View.OVER_SCROLL_ALWAYS);
}
}
} catch (Exception e) {
e.printStackTrace();
}
*/
}
}
3. 데모 인터페이스
package com.example.pulldownview;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.example.pulldownview.PullDownView.OnPullDownListener;
public class MainActivity extends Activity {
private PullDownView pullDownView;
private ScrollOverListView listView;
private MyAdapter adapter;
private List<String> arrays;
private LayoutInflater inflater;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inflater = getLayoutInflater();
pullDownView = (PullDownView) findViewById(R.id.pulldownview);
pullDownView.enableAutoFetchMore(true, 0);
listView = pullDownView.getListView();
adapter = new MyAdapter();
listView.setAdapter(adapter);
initArrays(new Handler(){
@Override
public void handleMessage(Message msg) {
arrays = (List<String>) msg.obj;
adapter.notifyDataSetChanged();
pullDownView.notifyDidDataLoad(false);
}
});
pullDownView.setOnPullDownListener(new OnPullDownListener() {
@Override
public void onRefresh() {
getNewString(new Handler(){
@Override
public void handleMessage(Message msg) {
arrays.add(0, (String) msg.obj);
adapter.notifyDataSetChanged();
pullDownView.notifyDidRefresh(arrays.isEmpty());
}
});
}
@Override
public void onLoadMore() {
getNewString(new Handler(){
@Override
public void handleMessage(Message msg) {
arrays.add((String) msg.obj);
adapter.notifyDataSetChanged();
pullDownView.notifyDidLoadMore(arrays.isEmpty());
}
});
}
});
}
private void initArrays(final Handler handler) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (Exception e) {
Thread.interrupted();
e.printStackTrace();
}
List<String> as = new ArrayList<String>();
as.add("first");
as.add("second");
as.add("third");
as.add("four");
as.add("five");
as.add("first");
as.add("second");
as.add("third");
as.add("four");
as.add("five");
as.add("first");
as.add("second");
as.add("third");
as.add("four");
as.add("five");
as.add("first");
as.add("second");
as.add("third");
as.add("four");
as.add("five");
as.add("first");
as.add("second");
as.add("third");
as.add("four");
as.add("five");
handler.obtainMessage(0, as).sendToTarget();
}
}).start();
}
private void getNewString(final Handler handler) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (Exception e) {
Thread.interrupted();
e.printStackTrace();
}
handler.obtainMessage(0, "New Text " + System.currentTimeMillis()).sendToTarget();
}
}).start();
}
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return arrays == null ? 0 : arrays.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.item_list, null);
holder.textView = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(arrays.get(position));
return convertView;
}
}
private static class ViewHolder {
TextView textView;
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.