땡겨서 새로고침 기능. Pull To Refresh.


이전에 사용하던 pull to refresh lib는 더이상 사용하지 않는 듯 하고 ...

안드로이드에서 제공하는 SwipeDrawer도 17부터 deprecated 돼버려서 ...

검색 해보니 커스텀 가능한 pull to refresh lib를 소개합니다.


"CustomSwipeRefreshLayout"


https://github.com/xyxyLiu/SwipeRefreshLayout

 
 


ListView, ViewPager, WebView 에서 사용 가능하고,

기존에 SwipeDrawer처럼 Progress Bar만 남기고 view가 사라지기도 하고,

기존의 pull to refresh처럼 현재 진행상태를 상단 view에서 표시하는 것도 가능합니다.


1. build.gradle에 아래 한 줄 추가 해 주시구요.

compile 'com.reginald.swiperefresh:library:1.1.0'


2. layout

(progress bar를 사용하지 않기 때문에 transparent로 지정했습니다.)

<com.reginald.swiperefresh.CustomSwipeRefreshLayout xmlns:swiperefresh="http://schemas.android.com/apk/res-auto"
android:id="@+id/layout_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
swiperefresh:enable_top_progress_bar="true"
swiperefresh:keep_refresh_head="true"
swiperefresh:refresh_mode="pull_mode"
swiperefresh:return_to_header_duration="500"
swiperefresh:return_to_top_duration="500"
swiperefresh:time_out_refresh_complete="500"
swiperefresh:time_out_return_to_top="500"
swiperefresh:top_progress_bar_color_1="@android:color/transparent"
swiperefresh:top_progress_bar_color_2="@android:color/transparent"
swiperefresh:top_progress_bar_color_3="@android:color/transparent"
swiperefresh:top_progress_bar_color_4="@android:color/transparent">

<RelativeLayout
android:id="@+id/rl_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>

</com.reginald.swiperefresh.CustomSwipeRefreshLayout>


3. MainActivity

public class MainActivity extends Activity {
private CustomSwipeRefreshLayout swipeRefreshLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// pull to refresh
swipeRefreshLayout = (CustomSwipeRefreshLayout) findViewById(R.id.layout_refresh);

swipeRefreshLayout.setCustomHeadview(new RefreshView(this));
swipeRefreshLayout.setTriggerDistance(50);
swipeRefreshLayout.setOnRefreshListener(new CustomSwipeRefreshLayout.OnRefreshListener() {
@Override

 swipeRefreshLayout.setOnRefreshListener(new CustomSwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
// refresh 처리
}
});

}


4. RefreshView

public class RefreshView extends LinearLayout implements CustomSwipeRefreshLayout.CustomSwipeRefreshHeadLayout {

private static final boolean DEBUG = false;

private static final SparseArray<String> STATE_MAP = new SparseArray<>();
private ViewGroup mContainer;
private ImageView mImageView;
private ImageView mProgressBar;
private int mState = -1;
private Animation loadingAnim;
private Context context;

{
STATE_MAP.put(0, "STATE_NORMAL");
STATE_MAP.put(1, "STATE_READY");
STATE_MAP.put(2, "STATE_REFRESHING");
STATE_MAP.put(3, "STATE_COMPLETE");
}

public RefreshView(Context context) {
super(context);
this.context = context;
setupLayout();
}

private void setupLayout() {
ViewGroup.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mContainer = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.view_main_refresh, null);
addView(mContainer, lp);
setGravity(Gravity.BOTTOM);
mImageView = (ImageView) findViewById(com.reginald.swiperefresh.R.id.default_header_arrow);
mProgressBar = (ImageView) findViewById(com.reginald.swiperefresh.R.id.default_header_progressbar);
loadingAnim = AnimationUtils.loadAnimation(context, R.anim.anim_loading_rotate);
setBackgroundColor(ContextCompat.getColor(context, android.R.color.transparent));
}

@Override
public void onStateChange(CustomSwipeRefreshLayout.State state, CustomSwipeRefreshLayout.State lastState) {
if (DEBUG)
Log.d("csrh", "onStateChange state = " + state + ", lastState = " + lastState);
int stateCode = state.getRefreshState();
int lastStateCode = lastState.getRefreshState();
float percent = state.getPercent();

switch (stateCode) {
case CustomSwipeRefreshLayout.State.STATE_NORMAL:
if (percent > 0.5f) {
setImageRotation((percent - 0.5f) * 180 / 0.5f);
} else {
setImageRotation(0);
}

if (stateCode != lastStateCode) {
//normal 상태처리
}
break;
case CustomSwipeRefreshLayout.State.STATE_READY:
if (stateCode != lastStateCode) {
//refresh 준비
setImageRotation(180);
}
break;
case CustomSwipeRefreshLayout.State.STATE_REFRESHING:
if (stateCode != lastStateCode) {
// refresh 중의 view처리
}
break;

case CustomSwipeRefreshLayout.State.STATE_COMPLETE:
if (stateCode != lastStateCode) {
// refresh가 끝난 후 view 처리
}
break;
default:
}
mState = stateCode;
}


private void setImageRotation(float rotation) {
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) {
mImageView.setRotation(rotation);
} else {
if (mImageView.getTag() == null){
mImageView.setTag(0f);
}
mImageView.clearAnimation();
Float lastDegree = (Float)mImageView.getTag();
RotateAnimation rotate = new RotateAnimation(lastDegree, rotation,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
mImageView.setTag(rotation);
rotate.setFillAfter(true);
mImageView.startAnimation(rotate);
}
}
}

 

+ Recent posts