Quellcode durchsuchen

通讯录页面上拉时,ABCD固定在导航栏下

RaoMeng vor 9 Jahren
Ursprung
Commit
750e228ad9
29 geänderte Dateien mit 1076 neuen und 26 gelöschten Zeilen
  1. 1 0
      WeiChat/build.gradle
  2. 34 7
      WeiChat/src/main/java/com/xzjmyk/pm/activity/adapter/FriendSortAdapter.java
  3. 18 14
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/fragment/ContactFragment.java
  4. 12 4
      WeiChat/src/main/res/layout/fragment_contact.xml
  5. 22 0
      WeiChat/src/main/res/layout/layout_head.xml
  6. 1 0
      library-refreshlayout/.gitignore
  7. 23 0
      library-refreshlayout/build.gradle
  8. 3 0
      library-refreshlayout/gradle.properties
  9. 17 0
      library-refreshlayout/proguard-rules.pro
  10. 1 0
      library-refreshlayout/src/main/AndroidManifest.xml
  11. 425 0
      library-refreshlayout/src/main/java/com/yalantis/phoenix/PullToRefreshView.java
  12. 81 0
      library-refreshlayout/src/main/java/com/yalantis/phoenix/refresh_view/BaseRefreshView.java
  13. 316 0
      library-refreshlayout/src/main/java/com/yalantis/phoenix/refresh_view/SunRefreshView.java
  14. 101 0
      library-refreshlayout/src/main/java/com/yalantis/phoenix/util/Logger.java
  15. 12 0
      library-refreshlayout/src/main/java/com/yalantis/phoenix/util/Utils.java
  16. BIN
      library-refreshlayout/src/main/res/drawable-hdpi/buildings.png
  17. BIN
      library-refreshlayout/src/main/res/drawable-hdpi/sky.png
  18. BIN
      library-refreshlayout/src/main/res/drawable-hdpi/sun.png
  19. BIN
      library-refreshlayout/src/main/res/drawable-mdpi/buildings.png
  20. BIN
      library-refreshlayout/src/main/res/drawable-mdpi/sky.png
  21. BIN
      library-refreshlayout/src/main/res/drawable-mdpi/sun.png
  22. BIN
      library-refreshlayout/src/main/res/drawable-xhdpi/buildings.png
  23. BIN
      library-refreshlayout/src/main/res/drawable-xhdpi/sky.png
  24. BIN
      library-refreshlayout/src/main/res/drawable-xhdpi/sun.png
  25. BIN
      library-refreshlayout/src/main/res/drawable-xxhdpi/buildings.png
  26. BIN
      library-refreshlayout/src/main/res/drawable-xxhdpi/sky.png
  27. BIN
      library-refreshlayout/src/main/res/drawable-xxhdpi/sun.png
  28. 8 0
      library-refreshlayout/src/main/res/values/attrs.xml
  29. 1 1
      settings.gradle

+ 1 - 0
WeiChat/build.gradle

@@ -127,4 +127,5 @@ dependencies {
     androidTestCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
     compile files('libs/pushservice-5.2.0.12.jar')
     compile 'se.emilsjolander:stickylistheaders:2.7.0'
+    compile project(':library-refreshlayout')
 }

+ 34 - 7
WeiChat/src/main/java/com/xzjmyk/pm/activity/adapter/FriendSortAdapter.java

@@ -27,7 +27,9 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-public class FriendSortAdapter extends BaseAdapter implements SectionIndexer {
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
+
+public class FriendSortAdapter extends BaseAdapter implements SectionIndexer,StickyListHeadersAdapter {
 
     private Context mContext;
     private List<BaseSortModel<Friend>> mSortFriends;
@@ -90,12 +92,12 @@ public class FriendSortAdapter extends BaseAdapter implements SectionIndexer {
             holder = (ViewHolder) convertView.getTag();
         }
         // 如果当前位置等于该分类首字母的Char的位置 ,则认为是第一次出现
-        if (position == getPositionForSection(section)) {
-            holder.tag_tv.setVisibility(View.VISIBLE);
-            holder.tag_tv.setText(mSortFriends.get(position).getFirstLetter());
-        } else {
-            holder.tag_tv.setVisibility(View.GONE);
-        }
+//        if (position == getPositionForSection(section)) {
+//            holder.tag_tv.setVisibility(View.VISIBLE);
+//            holder.tag_tv.setText(mSortFriends.get(position).getFirstLetter());
+//        } else {
+//            holder.tag_tv.setVisibility(View.GONE);
+//        }
         Friend friend = mSortFriends.get(position).getBean();
         final String phone = friend.getPhone();
         if (!StringUtils.isEmpty(phone)) {
@@ -202,6 +204,31 @@ public class FriendSortAdapter extends BaseAdapter implements SectionIndexer {
         return null;
     }
 
+    @Override
+    public View getHeaderView(int position, View convertView, ViewGroup parent) {
+        HeaderViewHolder viewHolder = null;
+        if (convertView == null){
+            convertView = LayoutInflater.from(mContext).inflate(R.layout.layout_head,parent,false);
+            viewHolder = new HeaderViewHolder();
+            viewHolder.cityLetterTextView = (TextView) convertView.findViewById(R.id.head);
+            convertView.setTag(viewHolder);
+        }else {
+            viewHolder = (HeaderViewHolder) convertView.getTag();
+        }
+        viewHolder.cityLetterTextView.setText(mSortFriends.get(position).getFirstLetter());
+
+        return convertView;
+    }
+
+    @Override
+    public long getHeaderId(int position) {
+        return mSortFriends.get(position).getFirstLetter().charAt(0);
+    }
+
+    class HeaderViewHolder{
+        TextView cityLetterTextView;
+    }
+
     class ViewHolder {
         TextView tag_tv;
         ImageView header_img;

+ 18 - 14
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/fragment/ContactFragment.java

@@ -16,13 +16,11 @@ import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.widget.AdapterView;
-import android.widget.ListView;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
-import com.handmark.pulltorefresh.library.PullToRefreshBase;
-import com.handmark.pulltorefresh.library.PullToRefreshListView;
 import com.lidroid.xutils.ViewUtils;
 import com.lidroid.xutils.view.annotation.ViewInject;
 import com.xzjmyk.pm.activity.AppConstant;
@@ -53,6 +51,7 @@ import com.xzjmyk.pm.activity.ui.message.NewFriendActivity;
 import com.xzjmyk.pm.activity.ui.nearby.UserSearchActivity;
 import com.xzjmyk.pm.activity.ui.tool.ThreadPool;
 import com.xzjmyk.pm.activity.view.ClearEditText;
+import com.yalantis.phoenix.PullToRefreshView;
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -65,6 +64,8 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
+
 
 /**
  * Created by pengminggong on 2016/10/12.
@@ -75,7 +76,7 @@ public class ContactFragment extends EasyFragment implements View.OnClickListene
     @ViewInject(R.id.text_dialog)
     private TextView text_dialog;
     @ViewInject(R.id.pull_refresh_list)
-    private PullToRefreshListView refreshListView;
+    private StickyListHeadersListView refreshListView;
     private FriendSortAdapter adapter;
     private DBManager manager;
     private String loginUserId;
@@ -84,12 +85,14 @@ public class ContactFragment extends EasyFragment implements View.OnClickListene
     private BaseComparator comparator;
     private ClearEditText search_edit;
     private CustomProgressDialog mcProgressDialog;
-
+    @ViewInject(R.id.contact_ptrv)
+    private PullToRefreshView mPullToRefreshView;
     private Handler handler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case 0x11:
+                    Toast.makeText(getActivity(), "网络加载成功", Toast.LENGTH_SHORT).show();
                     writeData(msg);
                     loadDataInThread();
                     break;
@@ -159,11 +162,11 @@ public class ContactFragment extends EasyFragment implements View.OnClickListene
                 // 该字母首次出现的位置
                 int position = adapter.getPositionForSection(s.charAt(0));
                 if (position != -1) {
-                    int count = refreshListView.getRefreshableView().getHeaderViewsCount();
-                    refreshListView.getRefreshableView().setSelection(position + count);
+                    int count = refreshListView.getHeaderViewsCount();
+                    refreshListView.setSelection(position + count);
                 }
                 if ("↑".equals(s)) {
-                    refreshListView.getRefreshableView().setSelection(1);
+                    refreshListView.setSelection(1);
                 }
             }
 
@@ -171,9 +174,10 @@ public class ContactFragment extends EasyFragment implements View.OnClickListene
             public void onTouchingUp() {
             }
         });
-        refreshListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() {
+        mPullToRefreshView.setOnRefreshListener(new PullToRefreshView.OnRefreshListener() {
             @Override
-            public void onRefresh(PullToRefreshBase<ListView> refreshView) {
+            public void onRefresh() {
+                Toast.makeText(getActivity(), "下拉刷新", Toast.LENGTH_SHORT).show();
                 loadDataInThread();
             }
         });
@@ -216,10 +220,9 @@ public class ContactFragment extends EasyFragment implements View.OnClickListene
         comparator = new BaseComparator();
         loginUserId = MyApplication.getInstance().mLoginUser.getUserId();
         setHeaderView();
-        refreshListView.setMode(PullToRefreshBase.Mode.PULL_FROM_START);
         sidebar.setTextView(text_dialog);
         adapter = new FriendSortAdapter(ct, showDatas);
-        refreshListView.getRefreshableView().setAdapter(adapter);
+        refreshListView.setAdapter(adapter);
         loadDataInThread();
         mcProgressDialog.show();
     }
@@ -227,7 +230,7 @@ public class ContactFragment extends EasyFragment implements View.OnClickListene
     /*设置头文件*/
     private void setHeaderView() {
         View headview = LayoutInflater.from(ct).inflate(R.layout.header_fragment_contact, null);
-        refreshListView.getRefreshableView().addHeaderView(headview);
+        refreshListView.addHeaderView(headview);
         search_edit = (ClearEditText) headview.findViewById(R.id.search_edit);
         headview.findViewById(R.id.company).setOnClickListener(this);//企业结构
         headview.findViewById(R.id.group).setOnClickListener(this);//商务群
@@ -408,7 +411,8 @@ public class ContactFragment extends EasyFragment implements View.OnClickListene
             @Override
             public void run() {
                 adapter.setData(showDatas);
-                refreshListView.onRefreshComplete();
+                mPullToRefreshView.setRefreshing(false);
+                Toast.makeText(getActivity(), "本地加载成功", Toast.LENGTH_SHORT).show();
                 if (mcProgressDialog.isShowing())
                     mcProgressDialog.dismiss();
             }

+ 12 - 4
WeiChat/src/main/res/layout/fragment_contact.xml

@@ -3,7 +3,7 @@
     android:layout_height="match_parent"
     android:background="@drawable/bg_main">
 
-    <com.handmark.pulltorefresh.library.PullToRefreshListView xmlns:ptr="http://schemas.android.com/apk/res-auto"
+    <!--<com.handmark.pulltorefresh.library.PullToRefreshListView xmlns:ptr="http://schemas.android.com/apk/res-auto"
         android:id="@+id/pull_refresh_list"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -17,9 +17,17 @@
         ptr:ptrMode="both"
         ptr:ptrOverScroll="false"
         ptr:ptrScrollingWhileRefreshingEnabled="true"
-        ptr:ptrShowIndicator="false" />
-
-
+        ptr:ptrShowIndicator="false"
+        android:visibility="gone"/>-->
+    <com.yalantis.phoenix.PullToRefreshView
+        android:id="@+id/contact_ptrv"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <se.emilsjolander.stickylistheaders.StickyListHeadersListView
+            android:id="@+id/pull_refresh_list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"/>
+    </com.yalantis.phoenix.PullToRefreshView>
     <TextView
         android:id="@+id/text_dialog"
         android:layout_width="80.0dip"

+ 22 - 0
WeiChat/src/main/res/layout/layout_head.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0.5px"
+        android:background="@color/gray_light"/>
+    <TextView
+        android:id="@+id/head"
+        android:layout_width="match_parent"
+        android:layout_height="30dp"
+        android:background="#faf9f9"
+        android:paddingLeft="10dp"
+        android:gravity="center_vertical"/>
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0.5px"
+        android:background="@color/gray_light"/>
+</LinearLayout>

+ 1 - 0
library-refreshlayout/.gitignore

@@ -0,0 +1 @@
+/build

+ 23 - 0
library-refreshlayout/build.gradle

@@ -0,0 +1,23 @@
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion 23
+    buildToolsVersion '23.0.2'
+
+    defaultConfig {
+        minSdkVersion 9
+        targetSdkVersion 23
+        versionCode 8
+        versionName "1.2.3"
+    }
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_7
+        targetCompatibility JavaVersion.VERSION_1_7
+    }
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile 'com.android.support:support-v4:23.1.1'
+}
+

+ 3 - 0
library-refreshlayout/gradle.properties

@@ -0,0 +1,3 @@
+POM_NAME=Phoenix
+POM_ARTIFACT_ID=phoenix
+POM_PACKAGING=aar

+ 17 - 0
library-refreshlayout/proguard-rules.pro

@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/baoyz/Developer/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

+ 1 - 0
library-refreshlayout/src/main/AndroidManifest.xml

@@ -0,0 +1 @@
+<manifest package="com.yalantis.phoenix"/>

+ 425 - 0
library-refreshlayout/src/main/java/com/yalantis/phoenix/PullToRefreshView.java

@@ -0,0 +1,425 @@
+package com.yalantis.phoenix;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.support.annotation.NonNull;
+import android.support.v4.view.MotionEventCompat;
+import android.support.v4.view.ViewCompat;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.Transformation;
+import android.widget.AbsListView;
+import android.widget.ImageView;
+
+import com.yalantis.phoenix.refresh_view.BaseRefreshView;
+import com.yalantis.phoenix.refresh_view.SunRefreshView;
+import com.yalantis.phoenix.util.Utils;
+
+import java.security.InvalidParameterException;
+
+public class PullToRefreshView extends ViewGroup {
+
+    private static final int DRAG_MAX_DISTANCE = 50;
+    private static final float DRAG_RATE = .5f;
+    private static final float DECELERATE_INTERPOLATION_FACTOR = 2f;
+
+    public static final int STYLE_SUN = 0;
+    public static final int MAX_OFFSET_ANIMATION_DURATION = 700;
+
+    private static final int INVALID_POINTER = -1;
+
+    private View mTarget;
+    private ImageView mRefreshView;
+    private Interpolator mDecelerateInterpolator;
+    private int mTouchSlop;
+    private int mTotalDragDistance;
+    private BaseRefreshView mBaseRefreshView;
+    private float mCurrentDragPercent;
+    private int mCurrentOffsetTop;
+    private boolean mRefreshing;
+    private int mActivePointerId;
+    private boolean mIsBeingDragged;
+    private float mInitialMotionY;
+    private int mFrom;
+    private float mFromDragPercent;
+    private boolean mNotify;
+    private OnRefreshListener mListener;
+
+    private int mTargetPaddingTop;
+    private int mTargetPaddingBottom;
+    private int mTargetPaddingRight;
+    private int mTargetPaddingLeft;
+
+    public PullToRefreshView(Context context) {
+        this(context, null);
+    }
+
+    public PullToRefreshView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RefreshView);
+        final int type = a.getInteger(R.styleable.RefreshView_type, STYLE_SUN);
+        a.recycle();
+
+        mDecelerateInterpolator = new DecelerateInterpolator(DECELERATE_INTERPOLATION_FACTOR);
+        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+        mTotalDragDistance = Utils.convertDpToPixel(context, DRAG_MAX_DISTANCE);
+
+        mRefreshView = new ImageView(context);
+
+        setRefreshStyle(type);
+
+        addView(mRefreshView);
+
+        setWillNotDraw(false);
+        ViewCompat.setChildrenDrawingOrderEnabled(this, true);
+    }
+
+    public void setRefreshStyle(int type) {
+        setRefreshing(false);
+        switch (type) {
+            case STYLE_SUN:
+                mBaseRefreshView = new SunRefreshView(getContext(), this);
+                break;
+            default:
+                throw new InvalidParameterException("Type does not exist");
+        }
+        mRefreshView.setImageDrawable(mBaseRefreshView);
+    }
+
+    /**
+     * This method sets padding for the refresh (progress) view.
+     */
+    public void setRefreshViewPadding(int left, int top, int right, int bottom) {
+        mRefreshView.setPadding(left, top, right, bottom);
+    }
+
+    public int getTotalDragDistance() {
+        return mTotalDragDistance;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        ensureTarget();
+        if (mTarget == null)
+            return;
+
+        widthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth() - getPaddingRight() - getPaddingLeft(), MeasureSpec.EXACTLY);
+        heightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight() - getPaddingTop() - getPaddingBottom(), MeasureSpec.EXACTLY);
+        mTarget.measure(widthMeasureSpec, heightMeasureSpec);
+        mRefreshView.measure(widthMeasureSpec, heightMeasureSpec);
+    }
+
+    private void ensureTarget() {
+        if (mTarget != null)
+            return;
+        if (getChildCount() > 0) {
+            for (int i = 0; i < getChildCount(); i++) {
+                View child = getChildAt(i);
+                if (child != mRefreshView) {
+                    mTarget = child;
+                    mTargetPaddingBottom = mTarget.getPaddingBottom();
+                    mTargetPaddingLeft = mTarget.getPaddingLeft();
+                    mTargetPaddingRight = mTarget.getPaddingRight();
+                    mTargetPaddingTop = mTarget.getPaddingTop();
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+
+        if (!isEnabled() || canChildScrollUp() || mRefreshing) {
+            return false;
+        }
+
+        final int action = MotionEventCompat.getActionMasked(ev);
+
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                setTargetOffsetTop(0, true);
+                mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
+                mIsBeingDragged = false;
+                final float initialMotionY = getMotionEventY(ev, mActivePointerId);
+                if (initialMotionY == -1) {
+                    return false;
+                }
+                mInitialMotionY = initialMotionY;
+                break;
+            case MotionEvent.ACTION_MOVE:
+                if (mActivePointerId == INVALID_POINTER) {
+                    return false;
+                }
+                final float y = getMotionEventY(ev, mActivePointerId);
+                if (y == -1) {
+                    return false;
+                }
+                final float yDiff = y - mInitialMotionY;
+                if (yDiff > mTouchSlop && !mIsBeingDragged) {
+                    mIsBeingDragged = true;
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mIsBeingDragged = false;
+                mActivePointerId = INVALID_POINTER;
+                break;
+            case MotionEventCompat.ACTION_POINTER_UP:
+                onSecondaryPointerUp(ev);
+                break;
+        }
+
+        return mIsBeingDragged;
+    }
+
+    @Override
+    public boolean onTouchEvent(@NonNull MotionEvent ev) {
+
+        if (!mIsBeingDragged) {
+            return super.onTouchEvent(ev);
+        }
+
+        final int action = MotionEventCompat.getActionMasked(ev);
+
+        switch (action) {
+            case MotionEvent.ACTION_MOVE: {
+                final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
+                if (pointerIndex < 0) {
+                    return false;
+                }
+
+                final float y = MotionEventCompat.getY(ev, pointerIndex);
+                final float yDiff = y - mInitialMotionY;
+                final float scrollTop = yDiff * DRAG_RATE;
+                mCurrentDragPercent = scrollTop / mTotalDragDistance;
+                if (mCurrentDragPercent < 0) {
+                    return false;
+                }
+                float boundedDragPercent = Math.min(1f, Math.abs(mCurrentDragPercent));
+                float extraOS = Math.abs(scrollTop) - mTotalDragDistance;
+                float slingshotDist = mTotalDragDistance;
+                float tensionSlingshotPercent = Math.max(0,
+                        Math.min(extraOS, slingshotDist * 2) / slingshotDist);
+                float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow(
+                        (tensionSlingshotPercent / 4), 2)) * 2f;
+                float extraMove = (slingshotDist) * tensionPercent / 2;
+                int targetY = (int) ((slingshotDist * boundedDragPercent) + extraMove);
+
+                mBaseRefreshView.setPercent(mCurrentDragPercent, true);
+                setTargetOffsetTop(targetY - mCurrentOffsetTop, true);
+                break;
+            }
+            case MotionEventCompat.ACTION_POINTER_DOWN:
+                final int index = MotionEventCompat.getActionIndex(ev);
+                mActivePointerId = MotionEventCompat.getPointerId(ev, index);
+                break;
+            case MotionEventCompat.ACTION_POINTER_UP:
+                onSecondaryPointerUp(ev);
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL: {
+                if (mActivePointerId == INVALID_POINTER) {
+                    return false;
+                }
+                final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
+                final float y = MotionEventCompat.getY(ev, pointerIndex);
+                final float overScrollTop = (y - mInitialMotionY) * DRAG_RATE;
+                mIsBeingDragged = false;
+                if (overScrollTop > mTotalDragDistance) {
+                    setRefreshing(true, true);
+                } else {
+                    mRefreshing = false;
+                    animateOffsetToStartPosition();
+                }
+                mActivePointerId = INVALID_POINTER;
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private void animateOffsetToStartPosition() {
+        mFrom = mCurrentOffsetTop;
+        mFromDragPercent = mCurrentDragPercent;
+        long animationDuration = Math.abs((long) (MAX_OFFSET_ANIMATION_DURATION * mFromDragPercent));
+
+        mAnimateToStartPosition.reset();
+        mAnimateToStartPosition.setDuration(animationDuration);
+        mAnimateToStartPosition.setInterpolator(mDecelerateInterpolator);
+        mAnimateToStartPosition.setAnimationListener(mToStartListener);
+        mRefreshView.clearAnimation();
+        mRefreshView.startAnimation(mAnimateToStartPosition);
+    }
+
+    private void animateOffsetToCorrectPosition() {
+        mFrom = mCurrentOffsetTop;
+        mFromDragPercent = mCurrentDragPercent;
+
+        mAnimateToCorrectPosition.reset();
+        mAnimateToCorrectPosition.setDuration(MAX_OFFSET_ANIMATION_DURATION);
+        mAnimateToCorrectPosition.setInterpolator(mDecelerateInterpolator);
+        mRefreshView.clearAnimation();
+        mRefreshView.startAnimation(mAnimateToCorrectPosition);
+
+        if (mRefreshing) {
+            mBaseRefreshView.start();
+            if (mNotify) {
+                if (mListener != null) {
+                    mListener.onRefresh();
+                }
+            }
+        } else {
+            mBaseRefreshView.stop();
+            animateOffsetToStartPosition();
+        }
+        mCurrentOffsetTop = mTarget.getTop();
+        mTarget.setPadding(mTargetPaddingLeft, mTargetPaddingTop, mTargetPaddingRight, mTotalDragDistance);
+    }
+
+    private final Animation mAnimateToStartPosition = new Animation() {
+        @Override
+        public void applyTransformation(float interpolatedTime, Transformation t) {
+            moveToStart(interpolatedTime);
+        }
+    };
+
+    private final Animation mAnimateToCorrectPosition = new Animation() {
+        @Override
+        public void applyTransformation(float interpolatedTime, Transformation t) {
+            int targetTop;
+            int endTarget = mTotalDragDistance;
+            targetTop = (mFrom + (int) ((endTarget - mFrom) * interpolatedTime));
+            int offset = targetTop - mTarget.getTop();
+
+            mCurrentDragPercent = mFromDragPercent - (mFromDragPercent - 1.0f) * interpolatedTime;
+            mBaseRefreshView.setPercent(mCurrentDragPercent, false);
+
+            setTargetOffsetTop(offset, false /* requires update */);
+        }
+    };
+
+    private void moveToStart(float interpolatedTime) {
+        int targetTop = mFrom - (int) (mFrom * interpolatedTime);
+        float targetPercent = mFromDragPercent * (1.0f - interpolatedTime);
+        int offset = targetTop - mTarget.getTop();
+
+        mCurrentDragPercent = targetPercent;
+        mBaseRefreshView.setPercent(mCurrentDragPercent, true);
+        mTarget.setPadding(mTargetPaddingLeft, mTargetPaddingTop, mTargetPaddingRight, mTargetPaddingBottom + targetTop);
+        setTargetOffsetTop(offset, false);
+    }
+
+    public void setRefreshing(boolean refreshing) {
+        if (mRefreshing != refreshing) {
+            setRefreshing(refreshing, false /* notify */);
+        }
+    }
+
+    private void setRefreshing(boolean refreshing, final boolean notify) {
+        if (mRefreshing != refreshing) {
+            mNotify = notify;
+            ensureTarget();
+            mRefreshing = refreshing;
+            if (mRefreshing) {
+                mBaseRefreshView.setPercent(1f, true);
+                animateOffsetToCorrectPosition();
+            } else {
+                animateOffsetToStartPosition();
+            }
+        }
+    }
+
+    private Animation.AnimationListener mToStartListener = new Animation.AnimationListener() {
+        @Override
+        public void onAnimationStart(Animation animation) {
+        }
+
+        @Override
+        public void onAnimationRepeat(Animation animation) {
+        }
+
+        @Override
+        public void onAnimationEnd(Animation animation) {
+            mBaseRefreshView.stop();
+            mCurrentOffsetTop = mTarget.getTop();
+        }
+    };
+
+    private void onSecondaryPointerUp(MotionEvent ev) {
+        final int pointerIndex = MotionEventCompat.getActionIndex(ev);
+        final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
+        if (pointerId == mActivePointerId) {
+            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+            mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
+        }
+    }
+
+    private float getMotionEventY(MotionEvent ev, int activePointerId) {
+        final int index = MotionEventCompat.findPointerIndex(ev, activePointerId);
+        if (index < 0) {
+            return -1;
+        }
+        return MotionEventCompat.getY(ev, index);
+    }
+
+    private void setTargetOffsetTop(int offset, boolean requiresUpdate) {
+        mTarget.offsetTopAndBottom(offset);
+        mBaseRefreshView.offsetTopAndBottom(offset);
+        mCurrentOffsetTop = mTarget.getTop();
+        if (requiresUpdate && android.os.Build.VERSION.SDK_INT < 11) {
+            invalidate();
+        }
+    }
+
+    private boolean canChildScrollUp() {
+        if (android.os.Build.VERSION.SDK_INT < 14) {
+            if (mTarget instanceof AbsListView) {
+                final AbsListView absListView = (AbsListView) mTarget;
+                return absListView.getChildCount() > 0
+                        && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
+                        .getTop() < absListView.getPaddingTop());
+            } else {
+                return mTarget.getScrollY() > 0;
+            }
+        } else {
+            return ViewCompat.canScrollVertically(mTarget, -1);
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+
+        ensureTarget();
+        if (mTarget == null)
+            return;
+
+        int height = getMeasuredHeight();
+        int width = getMeasuredWidth();
+        int left = getPaddingLeft();
+        int top = getPaddingTop();
+        int right = getPaddingRight();
+        int bottom = getPaddingBottom();
+
+        mTarget.layout(left, top + mCurrentOffsetTop, left + width - right, top + height - bottom + mCurrentOffsetTop);
+        mRefreshView.layout(left, top, left + width - right, top + height - bottom);
+    }
+
+    public void setOnRefreshListener(OnRefreshListener listener) {
+        mListener = listener;
+    }
+
+    public interface OnRefreshListener {
+        void onRefresh();
+    }
+
+}
+

+ 81 - 0
library-refreshlayout/src/main/java/com/yalantis/phoenix/refresh_view/BaseRefreshView.java

@@ -0,0 +1,81 @@
+package com.yalantis.phoenix.refresh_view;
+
+import android.content.Context;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+
+import com.yalantis.phoenix.PullToRefreshView;
+
+public abstract class BaseRefreshView extends Drawable implements Drawable.Callback, Animatable {
+
+    private PullToRefreshView mRefreshLayout;
+    private boolean mEndOfRefreshing;
+
+    public BaseRefreshView(Context context, PullToRefreshView layout) {
+        mRefreshLayout = layout;
+    }
+
+    public Context getContext() {
+        return mRefreshLayout != null ? mRefreshLayout.getContext() : null;
+    }
+
+    public PullToRefreshView getRefreshLayout() {
+        return mRefreshLayout;
+    }
+
+    public abstract void setPercent(float percent, boolean invalidate);
+
+    public abstract void offsetTopAndBottom(int offset);
+
+    @Override
+    public void invalidateDrawable(@NonNull Drawable who) {
+        final Callback callback = getCallback();
+        if (callback != null) {
+            callback.invalidateDrawable(this);
+        }
+    }
+
+    @Override
+    public void scheduleDrawable(Drawable who, Runnable what, long when) {
+        final Callback callback = getCallback();
+        if (callback != null) {
+            callback.scheduleDrawable(this, what, when);
+        }
+    }
+
+    @Override
+    public void unscheduleDrawable(Drawable who, Runnable what) {
+        final Callback callback = getCallback();
+        if (callback != null) {
+            callback.unscheduleDrawable(this, what);
+        }
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter cf) {
+
+    }
+
+    /**
+     * Our animation depend on type of current work of refreshing.
+     * We should to do different things when it's end of refreshing
+     *
+     * @param endOfRefreshing - we will check current state of refresh with this
+     */
+    public void setEndOfRefreshing(boolean endOfRefreshing) {
+        mEndOfRefreshing = endOfRefreshing;
+    }
+}

+ 316 - 0
library-refreshlayout/src/main/java/com/yalantis/phoenix/refresh_view/SunRefreshView.java

@@ -0,0 +1,316 @@
+package com.yalantis.phoenix.refresh_view;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.Animatable;
+import android.view.animation.Animation;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+import android.view.animation.Transformation;
+
+import com.yalantis.phoenix.PullToRefreshView;
+import com.yalantis.phoenix.R;
+import com.yalantis.phoenix.util.Utils;
+
+/**
+ * Created by Oleksii Shliama on 22/12/2014.
+ * https://dribbble.com/shots/1650317-Pull-to-Refresh-Rentals
+ */
+public class SunRefreshView extends BaseRefreshView implements Animatable {
+
+    private static final float SCALE_START_PERCENT = 0.5f;
+    private static final int ANIMATION_DURATION = 1000;
+
+    private final static float SKY_RATIO = 0.65f;
+    private static final float SKY_INITIAL_SCALE = 1.05f;
+
+    private final static float TOWN_RATIO = 0.22f;
+    private static final float TOWN_INITIAL_SCALE = 1.20f;
+    private static final float TOWN_FINAL_SCALE = 1.30f;
+
+    private static final float SUN_FINAL_SCALE = 0.75f;
+    private static final float SUN_INITIAL_ROTATE_GROWTH = 1.2f;
+    private static final float SUN_FINAL_ROTATE_GROWTH = 1.5f;
+
+    private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
+
+    private PullToRefreshView mParent;
+    private Matrix mMatrix;
+    private Animation mAnimation;
+
+    private int mTop;
+    private int mScreenWidth;
+
+    private int mSkyHeight;
+    private float mSkyTopOffset;
+    private float mSkyMoveOffset;
+
+    private int mTownHeight;
+    private float mTownInitialTopOffset;
+    private float mTownFinalTopOffset;
+    private float mTownMoveOffset;
+
+    private int mSunSize = 100;
+    private float mSunLeftOffset;
+    private float mSunTopOffset;
+
+    private float mPercent = 0.0f;
+    private float mRotate = 0.0f;
+
+    private Bitmap mSky;
+    private Bitmap mSun;
+    private Bitmap mTown;
+
+    private boolean isRefreshing = false;
+
+    public SunRefreshView(Context context, final PullToRefreshView parent) {
+        super(context, parent);
+        mParent = parent;
+        mMatrix = new Matrix();
+
+        setupAnimations();
+        parent.post(new Runnable() {
+            @Override
+            public void run() {
+                initiateDimens(parent.getWidth());
+            }
+        });
+    }
+
+    public void initiateDimens(int viewWidth) {
+        if (viewWidth <= 0 || viewWidth == mScreenWidth) return;
+
+        mScreenWidth = viewWidth;
+        mSkyHeight = (int) (SKY_RATIO * mScreenWidth);
+        mSkyTopOffset = (mSkyHeight * 0.38f);
+        mSkyMoveOffset = Utils.convertDpToPixel(getContext(), 15);
+
+//        mTownHeight = (int) (TOWN_RATIO * mScreenWidth);
+        mTownHeight = mParent.getTotalDragDistance();
+
+        mTownInitialTopOffset = (mParent.getTotalDragDistance() - mTownHeight * TOWN_INITIAL_SCALE);
+        mTownFinalTopOffset = (mParent.getTotalDragDistance() - mTownHeight * TOWN_FINAL_SCALE);
+        mTownMoveOffset = Utils.convertDpToPixel(getContext(), 10);
+
+        mSunLeftOffset = 0.3f * (float) mScreenWidth;
+        mSunTopOffset = (mParent.getTotalDragDistance() * 0.2f);
+
+        mTop = -mParent.getTotalDragDistance();
+
+        createBitmaps();
+    }
+
+    private void createBitmaps() {
+        final BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inPreferredConfig = Bitmap.Config.RGB_565;
+
+        mSky = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.sky, options);
+        mSky = Bitmap.createScaledBitmap(mSky, mScreenWidth, mSkyHeight, true);
+        mTown = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.buildings, options);
+        mTown = Bitmap.createScaledBitmap(mTown, mScreenWidth, (int) (mScreenWidth * TOWN_RATIO), true);
+        mSun = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.sun, options);
+        mSun = Bitmap.createScaledBitmap(mSun, mSunSize, mSunSize, true);
+    }
+
+    @Override
+    public void setPercent(float percent, boolean invalidate) {
+        setPercent(percent);
+        if (invalidate) setRotate(percent);
+    }
+
+    @Override
+    public void offsetTopAndBottom(int offset) {
+        mTop += offset;
+        invalidateSelf();
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mScreenWidth <= 0) return;
+
+        final int saveCount = canvas.save();
+
+        canvas.translate(0, mTop);
+        canvas.clipRect(0, -mTop, mScreenWidth, mParent.getTotalDragDistance());
+
+        drawSky(canvas);
+        drawTown(canvas);
+        drawSun(canvas);
+
+        canvas.restoreToCount(saveCount);
+    }
+
+    private void drawSky(Canvas canvas) {
+        Matrix matrix = mMatrix;
+        matrix.reset();
+
+        float dragPercent = Math.min(1f, Math.abs(mPercent));
+
+        float skyScale;
+        float scalePercentDelta = dragPercent - SCALE_START_PERCENT;
+        if (scalePercentDelta > 0) {
+            /** Change skyScale between {@link #SKY_INITIAL_SCALE} and 1.0f depending on {@link #mPercent} */
+            float scalePercent = scalePercentDelta / (1.0f - SCALE_START_PERCENT);
+            skyScale = SKY_INITIAL_SCALE - (SKY_INITIAL_SCALE - 1.0f) * scalePercent;
+        } else {
+            skyScale = SKY_INITIAL_SCALE;
+        }
+
+        float offsetX = -(mScreenWidth * skyScale - mScreenWidth) / 2.0f;
+        float offsetY = (1.0f - dragPercent) * mParent.getTotalDragDistance() - mSkyTopOffset // Offset canvas moving
+                - mSkyHeight * (skyScale - 1.0f) / 2 // Offset sky scaling
+                + mSkyMoveOffset * dragPercent; // Give it a little move top -> bottom
+
+        matrix.postScale(skyScale, skyScale);
+        matrix.postTranslate(offsetX, offsetY);
+        canvas.drawBitmap(mSky, matrix, null);
+    }
+
+    private void drawTown(Canvas canvas) {
+        Matrix matrix = mMatrix;
+        matrix.reset();
+
+        float dragPercent = Math.min(1f, Math.abs(mPercent));
+
+        float townScale;
+        float townTopOffset;
+        float townMoveOffset;
+        float scalePercentDelta = dragPercent - SCALE_START_PERCENT;
+        if (scalePercentDelta > 0) {
+            /**
+             * Change townScale between {@link #TOWN_INITIAL_SCALE} and {@link #TOWN_FINAL_SCALE} depending on {@link #mPercent}
+             * Change townTopOffset between {@link #mTownInitialTopOffset} and {@link #mTownFinalTopOffset} depending on {@link #mPercent}
+             */
+            float scalePercent = scalePercentDelta / (1.0f - SCALE_START_PERCENT);
+            townScale = TOWN_INITIAL_SCALE + (TOWN_FINAL_SCALE - TOWN_INITIAL_SCALE) * scalePercent;
+            townTopOffset = mTownInitialTopOffset - (mTownFinalTopOffset - mTownInitialTopOffset) * scalePercent;
+            townMoveOffset = mTownMoveOffset * (1.0f - scalePercent);
+        } else {
+            float scalePercent = dragPercent / SCALE_START_PERCENT;
+            townScale = TOWN_INITIAL_SCALE;
+            townTopOffset = mTownInitialTopOffset;
+            townMoveOffset = mTownMoveOffset * scalePercent;
+        }
+
+        float offsetX = -(mScreenWidth * townScale - mScreenWidth) / 2.0f;
+        float offsetY = (1.0f - dragPercent) * mParent.getTotalDragDistance() // Offset canvas moving
+                + townTopOffset
+                - mTownHeight * (townScale - 1.0f) / 2 // Offset town scaling
+                + townMoveOffset; // Give it a little move
+
+        matrix.postScale(townScale, townScale);
+        matrix.postTranslate(offsetX, offsetY);
+
+//        canvas.drawBitmap(mTown, matrix, null);
+        Paint paint = new Paint();
+        paint.setColor(Color.BLACK);
+        paint.setTextSize(40);
+        canvas.drawText("下拉刷新",mScreenWidth/2 - paint.measureText("下拉刷新")/2,mParent.getTotalDragDistance()/2+8,paint);
+    }
+
+    private void drawSun(Canvas canvas) {
+        Matrix matrix = mMatrix;
+        matrix.reset();
+
+        float dragPercent = mPercent;
+        if (dragPercent > 1.0f) { // Slow down if pulling over set height
+            dragPercent = (dragPercent + 9.0f) / 10;
+        }
+
+        float sunRadius = (float) mSunSize / 2.0f;
+        float sunRotateGrowth = SUN_INITIAL_ROTATE_GROWTH;
+
+        float offsetX = mSunLeftOffset;
+        float offsetY = mSunTopOffset
+                + (mParent.getTotalDragDistance() / 2) * (1.0f - dragPercent) // Move the sun up
+                - mTop; // Depending on Canvas position
+
+        float scalePercentDelta = dragPercent - SCALE_START_PERCENT;
+        if (scalePercentDelta > 0) {
+            float scalePercent = scalePercentDelta / (1.0f - SCALE_START_PERCENT);
+            float sunScale = 1.0f - (1.0f - SUN_FINAL_SCALE) * scalePercent;
+            sunRotateGrowth += (SUN_FINAL_ROTATE_GROWTH - SUN_INITIAL_ROTATE_GROWTH) * scalePercent;
+
+            matrix.preTranslate(offsetX + (sunRadius - sunRadius * sunScale), offsetY * (2.0f - sunScale));
+            matrix.preScale(sunScale, sunScale);
+
+            offsetX += sunRadius;
+            offsetY = offsetY * (2.0f - sunScale) + sunRadius * sunScale;
+        } else {
+            matrix.postTranslate(offsetX, offsetY);
+
+            offsetX += sunRadius;
+            offsetY += sunRadius;
+        }
+
+        matrix.postRotate(
+                (isRefreshing ? 360 : -360) * mRotate * (isRefreshing ? 1 : sunRotateGrowth),
+                offsetX,
+                offsetY);
+
+        canvas.drawBitmap(mSun, matrix, null);
+    }
+
+    public void setPercent(float percent) {
+        mPercent = percent;
+    }
+
+    public void setRotate(float rotate) {
+        mRotate = rotate;
+        invalidateSelf();
+    }
+
+    public void resetOriginals() {
+        setPercent(0);
+        setRotate(0);
+    }
+
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        super.onBoundsChange(bounds);
+    }
+
+    @Override
+    public void setBounds(int left, int top, int right, int bottom) {
+        super.setBounds(left, top, right, mSkyHeight + top);
+    }
+
+    @Override
+    public boolean isRunning() {
+        return false;
+    }
+
+    @Override
+    public void start() {
+        mAnimation.reset();
+        isRefreshing = true;
+        mParent.startAnimation(mAnimation);
+    }
+
+    @Override
+    public void stop() {
+        mParent.clearAnimation();
+        isRefreshing = false;
+        resetOriginals();
+    }
+
+    private void setupAnimations() {
+        mAnimation = new Animation() {
+            @Override
+            public void applyTransformation(float interpolatedTime, Transformation t) {
+                setRotate(interpolatedTime);
+            }
+        };
+        mAnimation.setRepeatCount(Animation.INFINITE);
+        mAnimation.setRepeatMode(Animation.RESTART);
+        mAnimation.setInterpolator(LINEAR_INTERPOLATOR);
+        mAnimation.setDuration(ANIMATION_DURATION);
+    }
+
+}

+ 101 - 0
library-refreshlayout/src/main/java/com/yalantis/phoenix/util/Logger.java

@@ -0,0 +1,101 @@
+package com.yalantis.phoenix.util;
+
+import android.text.TextUtils;
+
+public final class Logger {
+
+    private static final String TAG = "Phoenix";
+
+    /**
+     * Set true or false if you want read logs or not
+     */
+    private static boolean logEnabled_d = false;
+    private static boolean logEnabled_i = false;
+    private static boolean logEnabled_e = false;
+
+    public static void d() {
+        if (logEnabled_d) {
+            android.util.Log.v(TAG, getLocation());
+        }
+    }
+
+    public static void d(String msg) {
+        if (logEnabled_d) {
+            android.util.Log.v(TAG, getLocation() + msg);
+        }
+    }
+
+    public static void i(String msg) {
+        if (logEnabled_i) {
+            android.util.Log.i(TAG, getLocation() + msg);
+        }
+    }
+
+    public static void i() {
+        if (logEnabled_i) {
+            android.util.Log.i(TAG, getLocation());
+        }
+    }
+
+    public static void e(String msg) {
+        if (logEnabled_e) {
+            android.util.Log.e(TAG, getLocation() + msg);
+        }
+    }
+
+    public static void e(String msg, Throwable e) {
+        if (logEnabled_e) {
+            android.util.Log.e(TAG, getLocation() + msg, e);
+        }
+    }
+
+    public static void e(Throwable e) {
+        if (logEnabled_e) {
+            android.util.Log.e(TAG, getLocation(), e);
+        }
+    }
+
+    public static void e() {
+        if (logEnabled_e) {
+            android.util.Log.e(TAG, getLocation());
+        }
+    }
+
+    private static String getLocation() {
+        final String className = Logger.class.getName();
+        final StackTraceElement[] traces = Thread.currentThread()
+                .getStackTrace();
+        boolean found = false;
+
+        for (StackTraceElement trace : traces) {
+            try {
+                if (found) {
+                    if (!trace.getClassName().startsWith(className)) {
+                        Class<?> clazz = Class.forName(trace.getClassName());
+                        return "[" + getClassName(clazz) + ":"
+                                + trace.getMethodName() + ":"
+                                + trace.getLineNumber() + "]: ";
+                    }
+                } else if (trace.getClassName().startsWith(className)) {
+                    found = true;
+                }
+            } catch (ClassNotFoundException ignored) {
+            }
+        }
+
+        return "[]: ";
+    }
+
+    private static String getClassName(Class<?> clazz) {
+        if (clazz != null) {
+            if (!TextUtils.isEmpty(clazz.getSimpleName())) {
+                return clazz.getSimpleName();
+            }
+
+            return getClassName(clazz.getEnclosingClass());
+        }
+
+        return "";
+    }
+
+}

+ 12 - 0
library-refreshlayout/src/main/java/com/yalantis/phoenix/util/Utils.java

@@ -0,0 +1,12 @@
+package com.yalantis.phoenix.util;
+
+import android.content.Context;
+
+public class Utils {
+
+    public static int convertDpToPixel(Context context, int dp) {
+        float density = context.getResources().getDisplayMetrics().density;
+        return Math.round((float) dp * density);
+    }
+
+}

BIN
library-refreshlayout/src/main/res/drawable-hdpi/buildings.png


BIN
library-refreshlayout/src/main/res/drawable-hdpi/sky.png


BIN
library-refreshlayout/src/main/res/drawable-hdpi/sun.png


BIN
library-refreshlayout/src/main/res/drawable-mdpi/buildings.png


BIN
library-refreshlayout/src/main/res/drawable-mdpi/sky.png


BIN
library-refreshlayout/src/main/res/drawable-mdpi/sun.png


BIN
library-refreshlayout/src/main/res/drawable-xhdpi/buildings.png


BIN
library-refreshlayout/src/main/res/drawable-xhdpi/sky.png


BIN
library-refreshlayout/src/main/res/drawable-xhdpi/sun.png


BIN
library-refreshlayout/src/main/res/drawable-xxhdpi/buildings.png


BIN
library-refreshlayout/src/main/res/drawable-xxhdpi/sky.png


BIN
library-refreshlayout/src/main/res/drawable-xxhdpi/sun.png


+ 8 - 0
library-refreshlayout/src/main/res/values/attrs.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <declare-styleable name="RefreshView">
+        <attr name="type" format="enum">
+            <enum name="sun" value="0" />
+        </attr>
+    </declare-styleable>
+</resources>

+ 1 - 1
settings.gradle

@@ -1,2 +1,2 @@
-include ':pullToRefershLibraryMy', ':materialdialogs', ':MPAndroidChart', ':libedittextformlibrary', ':libfloatingactionbutton', ':libbdupdatesdk', ':library-viewpager-indicator', ':library-swipemenu_lv', ':lib-zxing'
+include ':pullToRefershLibraryMy', ':materialdialogs', ':MPAndroidChart', ':libedittextformlibrary', ':libfloatingactionbutton', ':libbdupdatesdk', ':library-viewpager-indicator', ':library-swipemenu_lv', ':lib-zxing', ':library-refreshlayout'
 include ':WeiChat'