Android XListView 는 드 롭 다운 새로 고침 과 위 에 더 많은 사용자 정의 RecyclerView 를 불 러 오 는 것 을 지원 합 니 다.
36152 단어 xlistviewrecyclerview새로 고침로드
드 롭 다운 리 셋:
로 딩
프로젝트 업데이트 과정 에서 XListView 를 recyclerView 로 바 꾸 는 수요 가 생 겼 고 바 꾼 후에 대체적으로 효과 가 변 하지 않 지만 드 롭 다운 리 셋 효과 에 대해 구 글 이 제시 한 해결 방안 은 RecyclerView 를 Swipe RefreshLayout 에 두 는 것 이다.그러나 이것 은 작은 원형 컨트롤 을 끌 어 내 려 실현 한 것 이다.XListView 의 header 효과 와 는 다 릅 니 다.인터넷 에서 다른 사람의 코드 를 많이 찾 았 지만 내 가 원 하 는 효 과 를 이 루 지 못 해 스스로 하 나 를 썼 다.
구체 적 으로 실현 되 는 효 과 는 다음 과 같다.
드 롭 다운 리 셋 기능:
1.탄력 있 는 드래그 효 과 를 실현 합 니 다.사고방식 은 XListView 를 참고 하고 recyclerView 의 position=0 의 위 치 는 header 레이아웃 을 놓 습 니 다.이 레이아웃 의 margin top 은 기본적으로 마이너스 레이아웃 높이 이기 때문에 이 레이아웃 은 화면 외부 에 있 습 니 다.아래 에서 끌 때 onTouchListener 를 통 해 손가락 의 이동 동태 에 따라 margin top 을 수정 하고 천천히 끌 어 냅 니 다.끌 어 내 는 거리,즉 margin top 이 정수 로 변 한 후에 캡 처 헤더 레이아웃 상 태 를 바 꾸 고 화살표 의 방향 을 바 꾸 고 제시 어 를 바 꿉 니 다.
2.탄력 있 는 리 턴 효 과 를 실현 합 니 다.timerTask 로 동적 으로 수 정 된 header 레이아웃 의 margin top 애니메이션 을 썼 습 니 다.일정한 시간 마다 margin top 의 값 을 줄 이 고 사용자 가 손 을 놓 을 때 함수 updateHeader Height()를 통 해 이 애니메이션 을 실행 합 니 다.
3.사용자 가 수 동 으로 끌 지 않 는 자동 새로 고침 효 과 를 실현 합 니 다.이 recyclerView 는 force Refresh()라 는 방법 도 있 습 니 다.사용자 가 수 동 으로 끌 지 않 아 도 머리 가 스스로 굴 러 나 온 다음 에 새로 고침 한 다음 에 스스로 걷 습 니 다.자동 으로 끌 어 내 리 는 것 도 하나의 timer Task 로 십 여 밀리초 마다 margin top 의 값 을 증가 시 켜 머리 를 천천히 드 러 냅 니 다.
위 에 더 많은 기능 을 불 러 옵 니 다:
1.끝까지 굴 러 가 는 부분 이 자동 으로 멈 추 는 효 과 를 실현 합 니 다.가끔 은 recyclerVIEW 가 너무 빨리 굴 러 가 고 끝까지 굴 러 갈 때 관성 에 따라 위로 날 아 갑 니 다.이곳 은 끝까지 recyclerView 의 굴 러 가 는 속 도 를 감시 합 니 다.만약 에 관성 굴 러 가 는 것 이 라 고 설명 하면 footer 구조의 높이 를 수정 하지 않 습 니 다.
2.위로 드래그 효과 구현:recyclerView 의 onScroll Listener 를 복사 하여 손가락 을 위로 굴 릴 때 updateFooter Height()방법 으로 바닥 footer View 의 margin bottom 을 동적 으로 수정 합 니 다.header View 와 마찬가지 로 손가락 이 이동 할 때 이 margin 을 따라 커지 게 하여 footer 레이아웃 의 높이 를 증가 시 키 고 손가락 이 인터넷 을 통 해 이동 합 니 다.증가 하 는 margin 의 높이 가 작 을 수록 탄력 있 는 상 당 김 효 과 를 실현 하여 오 작 동 을 방지 합 니 다.
3.자동 리 턴 효 과 를 실현 합 니 다.footer 레이아웃 을 감시 하 는 margin bottom 을 통 해 손 을 놓 을 때 새로 고침 을 시작 해 야 하 는 지 확인 합 니 다.margin bottom 이 어느 가치 가 있 을 때 footer 레이아웃 을 수정 하 는 상태 가 normal 에서 ready 로 바 뀌 고 ready 상태 에서 손 을 놓 으 면 새로 고침 작업 을 시작 합 니 다.리 턴 도 header 레이아웃 처럼 하나의 timerTask 를 통 해 10 밀리초 마다 margin 의 크기 를 수정 하여 리 턴 효 과 를 실현 합 니 다.
주의사항:
1.머리 와 밑부분 의 코드 분 리 를 실현 하기 위해 머리 는 onTouchListener 를 사용 하고 바닥 은 onScrollListener 를 사용 합 니 다.
2.본 recyclerVIEW 에 layoutManager 가 내장 되 어 있 으 므 로 recyclerView 에 layoutManager 를 다시 설정 하지 마 십시오.그렇지 않 으 면 머리 가 나 오지 않 고 빈 지침 을 내 려 놓 는 상황 이 발생 할 수 있 습 니 다.밑 에 나타 나 지만 미 끄 러 지 는 것 은 효과 가 없습니다.
3.이 recyclerView 에는 adapter 로 추상 적 인 클래스 가 내장 되 어 있 습 니 다.이 내 장 된 Alx Drag RecyclerView Adapter 를 계승 하여 사용 하거나 이 안의 논리 에 따라 adapter 를 다시 쓰 십시오.
다른 질문 있 으 시 면 저 한테 물 어보 세 요.
4.일부 자주 사용 하 는 기능,예 를 들 어 이 컨트롤 이 드 롭 다운 로드 와 업 로드 리 셋 을 지원 할 수 있 는 지 설정 하 는 등 api 인 터 페 이 스 는 XListView 의 용법 을 직접 참고 하면 됩 니 다.
사용 방법:
AlxDragRecyclerView Adapter 를 계승 하여 adapter 를 쓰 고 두 가지 종 류 를 각각 OnRefreshListener 와 LoadMoreListener 를 실현 합 니 다.구체 적 인 리 셋 논 리 를 안에 쓰 고 데 이 터 를 표시 할 준 비 를 한 후에 adapter 의 notifyDataSetChanged()방법 이나 notifyItemInserted()방법 을 호출 합 니 다.이 recyclerView 의 stopLoadmore()방법 과 stopRefresh()방법 을 실행 합 니 다.
다음은 코드 입 니 다.이 컨트롤 은 머리,아래쪽 레이아웃 컨트롤(CustomDragHeaderView,CustomDragFooterView),adapter,layoutmanager 를 포함 하여 내부 클래스 로 통합 되 어 이전 시의 복잡 도 를 줄 입 니 다.
import android.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.xxx.app.R;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by Alex on 2016/1/27.
*/
public class AlxRefreshLoadMoreRecyclerView extends RecyclerView {
private int footerHeight = -1;
LinearLayoutManager layoutManager;
// -- footer view
private CustomDragRecyclerFooterView mFooterView;
private boolean mEnablePullLoad;
private boolean mPullLoading;
private boolean isBottom;
private boolean mIsFooterReady = false;
private LoadMoreListener loadMoreListener;
// -- header view
private CustomDragHeaderView mHeaderView;
private boolean mEnablePullRefresh = true;
private boolean mIsRefreshing;
private boolean isHeader;
private boolean mIsHeaderReady = false;
private Timer timer;
private float oldY;
Handler handler = new Handler();
private OnRefreshListener refreshListener;
private AlxDragRecyclerViewAdapter adapter;
private int maxPullHeight = 50;// px
private static final int HEADER_HEIGHT = 68;// 68dp
private static final int MAX_PULL_LENGTH = 150;// 150dp
private OnClickListener footerClickListener;
public AlxRefreshLoadMoreRecyclerView(Context context) {
super(context);
initView(context);
}
public AlxRefreshLoadMoreRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public AlxRefreshLoadMoreRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
public void setAdapter(AlxDragRecyclerViewAdapter adapter){
super.setAdapter(adapter);
this.adapter = adapter;
}
public boolean ismPullLoading() {
return mPullLoading;
}
public boolean ismIsRefreshing() {
return mIsRefreshing;
}
private void updateFooterHeight(float delta) {
if(mFooterView==null)return;
int bottomMargin = mFooterView.getBottomMargin();
// Log.i("Alex3"," delta "+delta);
if(delta>50)delta = delta/6;
if(delta>0) {//
if(bottomMargin>maxPullHeight)delta = delta*0.65f;
else if(bottomMargin>maxPullHeight * 0.83333f)delta = delta*0.7f;
else if(bottomMargin>maxPullHeight * 0.66667f)delta = delta*0.75f;
else if(bottomMargin>maxPullHeight >> 1)delta = delta*0.8f;
else if(bottomMargin>maxPullHeight * 0.33333f)delta = delta*0.85f;
else if(bottomMargin>maxPullHeight * 0.16667F && delta > 20)delta = delta*0.2f;//
else if(bottomMargin>maxPullHeight * 0.16667F)delta = delta*0.9f;
// Log.i("Alex3","bottomMargin "+mFooterView.getBottomMargin()+" delta "+delta);
}
int height = mFooterView.getBottomMargin() + (int) (delta+0.5);
if (mEnablePullLoad && !mPullLoading) {
if (height > 150){//
// if (height > 1){//
mFooterView.setState(CustomDragRecyclerFooterView.STATE_READY);
mIsFooterReady = true;
// Log.i("Alex2", "ready");
} else {
mFooterView.setState(CustomDragRecyclerFooterView.STATE_NORMAL);
mIsFooterReady = false;
// Log.i("Alex2", "nomal");
}
}
mFooterView.setBottomMargin(height);
}
private void resetFooterHeight() {
int bottomMargin = mFooterView.getBottomMargin();
if (bottomMargin > 20) {
Log.i("Alex2", " ,margin " + bottomMargin + " " + footerHeight);
this.smoothScrollBy(0,-bottomMargin);
//
if(mIsFooterReady){
startLoadMore();
}
}
}
public void setLoadMoreListener(LoadMoreListener listener){
this.loadMoreListener = listener;
}
public void initView(Context context){
layoutManager = new LinearLayoutManager(context);// layoutManager,
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
int height = wm.getDefaultDisplay().getHeight();
layoutManager.offsetChildrenVertical(height*2);// 2/3
this.setLayoutManager(layoutManager);
// Log.i("Alex", " " + getContext().getResources().getDisplayMetrics().density);
maxPullHeight = dp2px(getContext().getResources().getDisplayMetrics().density,MAX_PULL_LENGTH);// 150dp
this.footerClickListener = new footerViewClickListener();
this.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
switch (newState){
case RecyclerView.SCROLL_STATE_IDLE:
// Log.i("Alex2", " || ");
if(isBottom)resetFooterHeight();
break;
case RecyclerView.SCROLL_STATE_DRAGGING:
// Log.i("Alex2", " , margin " + (mFooterView == null ? "" : mFooterView.getBottomMargin()));
break;
case RecyclerView.SCROLL_STATE_SETTLING:
// Log.i("Alex2", " ");
break;
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int lastItemPosition = layoutManager.findLastVisibleItemPosition();
// Log.i("Alex2","mEnable "+mEnablePullLoad+"lastitemPosition "+lastItemPosition+" itemcount "+layoutManager.getItemCount());
if(lastItemPosition == layoutManager.getItemCount()-1 && mEnablePullLoad) {//
isBottom = true;
mFooterView = (CustomDragRecyclerFooterView)layoutManager.findViewByPosition(layoutManager.findLastVisibleItemPosition());// hide, hide footerview
// Log.i("Alex2"," !!"+"mfooterView "+mFooterView);
if(mFooterView!=null) mFooterView.setOnClickListener(footerClickListener);
if(footerHeight==-1 && mFooterView!=null){
mFooterView.show();
mFooterView.setState(CustomDragRecyclerFooterView.STATE_NORMAL);
footerHeight = mFooterView.getMeasuredHeight();//
// Log.i("Alex2", " " + footerHeight);
}
updateFooterHeight(dy);
}else if(lastItemPosition == layoutManager.getItemCount()-1 && mEnablePullLoad){//
startLoadMore();//
}
else {
isBottom = false;
}
}
});
}
/**
*
*
* @param enable
*/
public void setPullLoadEnable(boolean enable) {
mPullLoading = false;
mEnablePullLoad = enable;
if(adapter!=null)adapter.setPullLoadMoreEnable(enable);//adapter recyclerView
if(mFooterView==null)return;
if (!mEnablePullLoad) {
// this.smoothScrollBy(0,-footerHeight);
mFooterView.hide();
mFooterView.setOnClickListener(null);
mFooterView.setBottomMargin(0);
//make sure "pull up" don't show a line in bottom when listview with one page
} else {
mFooterView.show();
mFooterView.setState(CustomDragRecyclerFooterView.STATE_NORMAL);
mFooterView.setVisibility(VISIBLE);
//make sure "pull up" don't show a line in bottom when listview with one page
// both "pull up" and "click" will invoke load more.
mFooterView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startLoadMore();
}
});
}
}
/**
* loadmore
*/
public void stopLoadMore() {
if (mPullLoading == true) {
mPullLoading = false;
if(mFooterView==null)return;
mFooterView.show();
mFooterView.setState(CustomDragRecyclerFooterView.STATE_ERROR);
}
}
private void startLoadMore() {
if(mPullLoading)return;
mPullLoading = true;
if(mFooterView!=null)mFooterView.setState(CustomDragRecyclerFooterView.STATE_LOADING);
Log.i("Alex2", " ");
mIsFooterReady = false;
if (loadMoreListener != null) {
loadMoreListener.onLoadMore();
}
}
/**
*
*/
public interface LoadMoreListener{
public void onLoadMore();
}
/**
* loadMore
*/
class footerViewClickListener implements OnClickListener {
@Override
public void onClick(View v) {
startLoadMore();
}
}
private void updateHeaderHeight(float delta) {
mHeaderView = (CustomDragHeaderView) layoutManager.findViewByPosition(0);
// Log.i("Alex2", " !!!! header " + mHeaderView.getHeight() + " margin " + mHeaderView.getTopMargin());//
// Log.i("Alex2", " margin" + mHeaderView.getTopMargin() +"delta "+delta);
if(delta>0){//
int topMargin = mHeaderView.getTopMargin();
if(topMargin>maxPullHeight * 0.33333f)delta = delta*0.5f;
else if(topMargin>maxPullHeight * 0.16667F)delta = delta*0.55f;
else if(topMargin>0)delta = delta*0.6f;
else if(topMargin<0)delta = delta*0.6f;//
mHeaderView.setTopMargin(mHeaderView.getTopMargin() + (int)delta);
} else{//
if(!mIsRefreshing || mHeaderView.getTopMargin()>0) {// margin
this.scrollBy(0, (int) delta);// ,
// Log.i("Alex2", " " + delta);
mHeaderView.setTopMargin(mHeaderView.getTopMargin() + (int) delta);
}
}
if(mHeaderView.getTopMargin()>0 && !mIsRefreshing){
mIsHeaderReady = true;
mHeaderView.setState(CustomDragHeaderView.STATE_READY);
}// ready
else if(!mIsRefreshing){
mIsHeaderReady = false;
mHeaderView.setState(CustomDragHeaderView.STATE_NORMAL);
}//
}
@Override
public void smoothScrollToPosition(final int position) {
super.smoothScrollToPosition(position);
final Timer scrollTimer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
int bottomCardPosition = layoutManager.findLastVisibleItemPosition();
if(bottomCardPosition<position+1){//
handler.post(new Runnable() {
@Override
public void run() {
smoothScrollBy(0,50);
}
});
}else if(bottomCardPosition>position){//
handler.post(new Runnable() {
@Override
public void run() {
smoothScrollBy(0,-50);
}
});
}else {
if(scrollTimer!=null)scrollTimer.cancel();
}
}
};
scrollTimer.schedule(timerTask,0,20);
}
/**
* ,
*/
private void smoothShowHeader(){
if(mHeaderView==null)return;
// if(layoutManager.findFirstVisibleItemPosition()!=0){// header
// mHeaderView.setTopMargin(0);
// return;
// }
if(timer!=null)timer.cancel();
final TimerTask timerTask = new TimerTask() {
@Override
public void run() {
if(mHeaderView==null){
if(timer!=null)timer.cancel();
return;
}
// Log.i("Alex2","topMargin "+mHeaderView.getTopMargin()+" height "+mHeaderView.getHeight());
if(mHeaderView.getTopMargin()<0){
handler.post(new Runnable() {
@Override
public void run() {
if (mIsRefreshing) {// ready
mHeaderView.setTopMargin(mHeaderView.getTopMargin() +2);
}
}
});
} else if(timer!=null){// , ,
timer.cancel();
}
}
};
timer = new Timer();
timer.scheduleAtFixedRate(timerTask,0,16);
}
/**
*
*/
private void resetHeaderHeight() {
if(mHeaderView==null)mHeaderView = (CustomDragHeaderView) layoutManager.findViewByPosition(0);
if(layoutManager.findFirstVisibleItemPosition()!=0){// header
mHeaderView.setTopMargin(-mHeaderView.getRealHeight());
return;
}
if(timer!=null)timer.cancel();
final TimerTask timerTask = new TimerTask() {
@Override
public void run() {
if(mHeaderView==null)return;
// Log.i("Alex2","topMargin "+mHeaderView.getTopMargin()+" height "+mHeaderView.getHeight());
if(mHeaderView.getTopMargin()>-mHeaderView.getRealHeight()){// header
handler.post(new Runnable() {
@Override
public void run() {
if (mIsHeaderReady || mIsRefreshing) {// ready
// Log.i("Alex2", " ready ");
int delta = mHeaderView.getTopMargin() / 9;
if (delta < 5) delta = 5;
if (mHeaderView.getTopMargin() > 0)
mHeaderView.setTopMargin(mHeaderView.getTopMargin() - delta);
} else {//
// Log.i("Alex2", " ");
mHeaderView.setTopMargin(mHeaderView.getTopMargin() - 5);
}
}
});
} else if(timer!=null){// , ,
timer.cancel();
handler.post(new Runnable() {
@Override
public void run() {
mHeaderView.setState(mHeaderView.STATE_FINISH);
}
});
}
}
};
timer = new Timer();
timer.scheduleAtFixedRate(timerTask,0,10);
}
/**
* onTouchEvent
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
int delta = (int)(event.getY()-oldY);
oldY = event.getY();
if (layoutManager.findViewByPosition(0) instanceof CustomDragHeaderView) {
isHeader = true;
updateHeaderHeight(delta);// margin
}else{
isHeader = false;
if(mHeaderView!=null && !mIsRefreshing)mHeaderView.setTopMargin(-mHeaderView.getRealHeight());
}
break;
// case MotionEvent.ACTION_DOWN:
// Log.i("Alex", "touch down");
// oldY = event.getY();
// if(timer!=null)timer.cancel();
// break;
case MotionEvent.ACTION_UP:
// Log.i("Alex", " !!!! touch up ");
if(mIsHeaderReady && !mIsRefreshing)startRefresh();
if(isHeader)resetHeaderHeight();//
break;
case MotionEvent.ACTION_CANCEL:
// Log.i("Alex", "touch cancel");
break;
}
return super.onTouchEvent(event);
}
/**
* onclickListener ,ontouch down ,
* @param ev
* @return
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// Log.i("Alex", "touch down ");
oldY = ev.getY();
if (timer != null) timer.cancel();
break;
}
return super.dispatchTouchEvent(ev);
}
public void setOnRefreshListener(OnRefreshListener listener){
this.refreshListener = listener;
}
/**
*
*
* @param enable
*/
public void setPullRefreshEnable(boolean enable) {
mIsRefreshing = false;
mEnablePullRefresh = enable;
if(mHeaderView==null)return;
if (!mEnablePullRefresh) {
mHeaderView.setOnClickListener(null);
} else {
mHeaderView.setState(CustomDragFooterView.STATE_NORMAL);
mHeaderView.setVisibility(VISIBLE);
}
}
/**
* ,
*/
public void stopRefresh() {
if (mIsRefreshing == true) {
mIsRefreshing = false;
mIsHeaderReady = false;
if(mHeaderView==null)return;
mHeaderView.setState(CustomDragFooterView.STATE_NORMAL);
resetHeaderHeight();
}
}
/**
* ,
*/
public void forceRefresh(){
if(mHeaderView==null)mHeaderView = (CustomDragHeaderView) layoutManager.findViewByPosition(0);
if(mHeaderView!=null)mHeaderView.setState(CustomDragHeaderView.STATE_REFRESHING);
mIsRefreshing = true;
Log.i("Alex2", " ");
mIsHeaderReady = false;
smoothShowHeader();
if (refreshListener != null)refreshListener.onRefresh();
}
private void startRefresh() {
mIsRefreshing = true;
mHeaderView.setState(CustomDragHeaderView.STATE_REFRESHING);
Log.i("Alex2", " ");
mIsHeaderReady = false;
if (refreshListener != null) refreshListener.onRefresh();
}
public interface OnRefreshListener{
public void onRefresh();
}
/**
* recycler view
*/
public static class CustomDragHeaderView extends LinearLayout {
public final static int STATE_NORMAL = 0;
public final static int STATE_READY = 1;
public final static int STATE_REFRESHING = 2;
public final static int STATE_FINISH = 3;
public float screenDensity;
private final int ROTATE_ANIM_DURATION = 180;
private Context mContext;
private View mContentView;
private View mProgressBar;
private ImageView mArrowImageView;
private TextView mHintTextView;
private Animation mRotateUpAnim;
private Animation mRotateDownAnim;
public CustomDragHeaderView(Context context) {
super(context);
initView(context);
}
public CustomDragHeaderView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
private int mState;
public void setState(int state) {
if (state == mState)
return;
if (state == STATE_REFRESHING) { //
mArrowImageView.clearAnimation();
mArrowImageView.setVisibility(View.INVISIBLE);
mProgressBar.setVisibility(View.VISIBLE);
} else { //
mArrowImageView.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.INVISIBLE);
}
switch (state) {
case STATE_NORMAL:
if (mState == STATE_READY) {
mArrowImageView.startAnimation(mRotateDownAnim);
mHintTextView.setText(R.string.xlistview_header_hint_normal);
}
else if (mState == STATE_REFRESHING) {//
// mArrowImageView.clearAnimation();
mArrowImageView.setVisibility(INVISIBLE);
mHintTextView.setText("load completed");
}
break;
case STATE_READY:
if (mState != STATE_READY) {
mArrowImageView.clearAnimation();
mArrowImageView.startAnimation(mRotateUpAnim);
}
mHintTextView.setText(R.string.xlistview_header_hint_ready);
break;
case STATE_REFRESHING:
mHintTextView.setText(R.string.xlistview_header_hint_loading);
break;
case STATE_FINISH:
mArrowImageView.setVisibility(View.VISIBLE);
mHintTextView.setText(R.string.xlistview_header_hint_normal);
break;
default:
}
mState = state;
}
public void setTopMargin(int height) {
if (mContentView==null) return ;
LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
lp.topMargin = height;
mContentView.setLayoutParams(lp);
}
//
public int getTopMargin() {
LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
return lp.topMargin;
}
public void setHeight(int height){
if (mContentView==null) return ;
LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
lp.height = height;
mContentView.setLayoutParams(lp);
}
private int realHeight;
/**
* headerView ,
* @return
*/
public int getRealHeight(){
return realHeight;
}
private void initView(Context context) {
mContext = context;
this.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));//recyclerView
LinearLayout moreView = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.xlistview_header, null);
addView(moreView);
moreView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
mContentView = moreView.findViewById(R.id.xlistview_header_content);
LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
Log.i("Alex", " height " + mContentView.getHeight());
lp.height = 150;// ,
screenDensity = getContext().getResources().getDisplayMetrics().density;// , px dp
lp.height = dp2px(screenDensity,HEADER_HEIGHT);// 75dp
realHeight = lp.height;
lp.topMargin = -lp.height;
mContentView.setLayoutParams(lp);
mArrowImageView = (ImageView) findViewById(R.id.xlistview_header_arrow);
mHintTextView = (TextView) findViewById(R.id.xlistview_header_hint_textview);
mHintTextView.setPadding(0,dp2px(screenDensity,3),0,0);// ,
mProgressBar = findViewById(R.id.xlistview_header_progressbar);
mRotateUpAnim = new RotateAnimation(0.0f, -180.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
mRotateUpAnim.setFillAfter(true);
mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
mRotateDownAnim.setFillAfter(true);
}
}
public static int dp2px(float density, int dp) {
if (dp == 0) {
return 0;
}
return (int) (dp * density + 0.5f);
}
public static class CustomDragRecyclerFooterView extends LinearLayout {
public final static int STATE_NORMAL = 0;
public final static int STATE_READY = 1;
public final static int STATE_LOADING = 2;
public final static int STATE_ERROR = 3;
private Context mContext;
private View mContentView;
private View mProgressBar;
private TextView mHintView;
public CustomDragRecyclerFooterView(Context context) {
super(context);
initView(context);
}
public CustomDragRecyclerFooterView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public void setState(int state) {
mProgressBar.setVisibility(View.INVISIBLE);
// mHintView.setVisibility(View.INVISIBLE);
if (state == STATE_READY) {
mHintView.setVisibility(View.VISIBLE);
mHintView.setText(" ");
} else if (state == STATE_LOADING) {
mProgressBar.setVisibility(View.VISIBLE);
mHintView.setVisibility(INVISIBLE);
} else if(state == STATE_ERROR){
mProgressBar.setVisibility(GONE);
mHintView.setVisibility(VISIBLE);
mHintView.setText(R.string.xlistview_footer_hint_ready);
}
else {
mHintView.setVisibility(View.VISIBLE);
mHintView.setText(R.string.xlistview_footer_hint_normal);
mHintView.setText("Load more");
}
}
public void setBottomMargin(int height) {
if (height < 0) return ;
LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
lp.bottomMargin = height;
mContentView.setLayoutParams(lp);
}
public int getBottomMargin() {
LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
return lp.bottomMargin;
}
/**
* normal status
*/
public void normal() {
mHintView.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
}
/**
* loading status
*/
public void loading() {
mHintView.setVisibility(View.GONE);
mProgressBar.setVisibility(View.VISIBLE);
}
/**
* hide footer when disable pull load more
*/
public void hide() {
LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
lp.height = 1;// 0 layoutManger
mContentView.setLayoutParams(lp);
mContentView.setBackgroundColor(Color.BLACK);//
}
/**
* show footer
*/
public void show() {
LayoutParams lp = (LayoutParams)mContentView.getLayoutParams();
lp.height = LayoutParams.WRAP_CONTENT;
lp.width = LayoutParams.MATCH_PARENT;
mContentView.setLayoutParams(lp);
mContentView.setBackgroundColor(Color.WHITE);//
}
private void initView(Context context) {
mContext = context;
this.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
LinearLayout moreView = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.layout_customdragfooterview, null);
addView(moreView);
moreView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
mContentView = moreView.findViewById(R.id.rlContentView);
mProgressBar = moreView.findViewById(R.id.pbContentView);
mHintView = (TextView)moreView.findViewById(R.id.ctvContentView);
mHintView.setText("load more");
// mProgressBar.setVisibility(VISIBLE);// ,
}
}
/**
* , recyclerView adapter
* @param <T>
*/
public static abstract class AlxDragRecyclerViewAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
protected static final int TYPE_HEADER = 436874;
protected static final int TYPE_ITEM = 256478;
protected static final int TYPE_FOOTER = 9621147;
private int ITEM;
private ViewHolder vhItem;
protected boolean loadMore;
private List<T> dataList;
public List<T> getDataList() {
return dataList;
}
public void setDataList(List<T> dataList) {
this.dataList = dataList;
}
public AlxDragRecyclerViewAdapter(List<T> dataList,int itemLayout,boolean pullEnable){
this.dataList = dataList;
this.ITEM = itemLayout;
this.loadMore = pullEnable;
}
public abstract ViewHolder setItemViewHolder(View itemView);
private T getObject(int position){
if(dataList!=null && dataList.size()>=position)return dataList.get(position-1);// header
return null;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_ITEM) {
//inflate your layout and pass it to view holder
View itemView = LayoutInflater.from(parent.getContext()).inflate(ITEM,null);
Log.i("Alex","itemView "+itemView);
this.vhItem = setItemViewHolder(itemView);
Log.i("Alex","vhItem "+vhItem);
return vhItem;
} else if (viewType == TYPE_HEADER) {
//inflate your layout and pass it to view holder
View headerView = new CustomDragHeaderView(parent.getContext());
return new VHHeader(headerView);
} else if(viewType==TYPE_FOOTER){
CustomDragRecyclerFooterView footerView = new CustomDragRecyclerFooterView(parent.getContext());
return new VHFooter(footerView);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}
public void setPullLoadMoreEnable(boolean enable){
this.loadMore = enable;
}
public boolean getPullLoadMoreEnable(){return loadMore;}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {// getView
Log.i("Alex"," "+position+" "+holder.getClass());
if (vhItem!=null && holder.getClass() == vhItem.getClass()) {
//cast holder to VHItem and set data
initItemView(holder,position,getObject(position));
}else if (holder instanceof AlxDragRecyclerViewAdapter.VHHeader) {
//cast holder to VHHeader and set data for header.
}else if(holder instanceof AlxDragRecyclerViewAdapter.VHFooter){
if(!loadMore)((VHFooter)holder).footerView.hide();// footerView
}
}
@Override
public int getItemCount() {
return (dataList==null ||dataList.size()==0)?1:dataList.size() + 2;// header, list 0 footView,
}// , 2
/**
* ViewHolder
* @param position
* @return
*/
@Override
public int getItemViewType(int position) {
if (position == 0)return TYPE_HEADER;
else if(isPositonFooter(position))return TYPE_FOOTER;
return TYPE_ITEM;
}
protected boolean isPositonFooter(int position){// position 0
if (dataList == null && position == 1) return true;// item
return position == dataList.size() + 1;// item( 0)
}
// class VHItem extends RecyclerView.ViewHolder {
// public VHItem(View itemView) {
// super(itemView);
// }
// public View getItemView(){return itemView;}
// }
//
protected class VHHeader extends RecyclerView.ViewHolder {
public VHHeader(View headerView) {
super(headerView);
}
}
protected class VHFooter extends RecyclerView.ViewHolder {
public CustomDragRecyclerFooterView footerView;
public VHFooter(View itemView) {
super(itemView);
footerView = (CustomDragRecyclerFooterView)itemView;
}
}
public abstract void initItemView(ViewHolder itemHolder,int posion,T entity);
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
RecyclerView에서 Paging의 활용그러나 Paging의 유일한 한계는 RecyclerView와 결합하여 사용해야 하며, 또한 독점적인 PagedListAdapter를 사용해야 한다는 것이다.이는 데이터를 하나의 Paged List 대상으로 통일적으로...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.