Android智能下拉刷新、上拉加載框架(一)——SmartRefreshLayout

在項目開發中或多或少都涉及到下拉刷新、上拉加載的效果,網上的第三方效果也有很多,當然也可以自己寫,這里就大致說下SmartRefreshLayout。
SmartRefreshLayout支持下拉刷新、上拉加載、二級刷新、淘寶二樓、RefreshLayout、OverScroll,Android智能下拉刷新框架,支持越界回彈、越界拖動,具有極強的擴展性,集成了幾十種炫酷的Header和 Footer,可以根據源碼自定義實現Header和 Footer效果;接下來就看下如何將其集成到自己的項目中;這里采用的是源碼集成的方式,非源碼集成的方式很簡單,可以參考SmartRefreshLayout github說明進行集成;
SmartRefreshLayout
根據上面的地址下載源碼;打開源碼會看到refresh-layout、refresh-header、refresh-footer、app-design等這幾個model庫;那就一個一個來弄;

refresh-layout

先將res目錄下的文件全部拷貝到自己對應model下面,將refresh-layout model中build.gradle里面的依賴庫拷貝到自己model中build.gradle文件中;

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    testCompile 'junit:junit:4.12'

    //noinspection GradleDependency
    compile 'com.android.support:support-annotations:25.1.0'
    //noinspection GradleDependency,GradleCompatible
    compile 'com.android.support:support-v4:22.1.0'
    //noinspection GradleDependency,GradleCompatible
    compile 'com.android.support:recyclerview-v7:21.0.0'
    //noinspection GradleDependency,GradleCompatible
    compile 'com.android.support:design:23.0.0'
}

將自己model下的AndroidManifest里面的包名改成com.scwang.smartrefresh.layout和它的一致,在新增model時弄為一致也可以,這樣拷貝源碼方便;將java目錄下的源碼拷貝到自己項目中rebuild下項目;refresh-layout弄沒有問題了,就來弄refresh-header;

refresh-header

build.gradle:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    testCompile 'junit:junit:4.12'

    //noinspection GradleDependency
    compile 'com.android.support:support-annotations:25.1.0'
    //noinspection GradleDependency,GradleCompatible
    compile 'com.android.support:support-v4:22.1.0'
    compile project(':refresh-layout')
}

和上面一樣,修改好包名(com.scwang.smartrefresh.header)并將源碼拷貝進來;資源和源碼拷貝好后,rebuild一下項目;refresh-footer、app-design這兩個model沒有什么用就沒有弄了;弄好后,就可以用下看看有哪些效果了。


GIF.gif
public class BezierCircleStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
    private enum Item {
        內容不偏移(R.string.item_style_content_translation_off),
        內容跟隨偏移(R.string.item_style_content_translation_on),
        橙色主題(R.string.item_style_theme_orange_abstract),
        紅色主題(R.string.item_style_theme_red_abstract),
        綠色主題(R.string.item_style_theme_green_abstract),
        藍色主題(R.string.item_style_theme_blue_abstract),;
        public int nameId;

        Item(@StringRes int nameId) {
            this.nameId = nameId;
        }
    }

    private Toolbar mToolbar;
    private RefreshLayout mRefreshLayout;
    private static boolean isFirstEnter = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_style_circle);
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        mRefreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);
        if (isFirstEnter) {
            isFirstEnter = false;
            mRefreshLayout.autoRefresh();//第一次進入觸發自動刷新,演示效果
        }
        View view = findViewById(R.id.recyclerView);
        if (view instanceof RecyclerView) {
            RecyclerView recyclerView = (RecyclerView) view;
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
//            recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL));
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            List<Item> items = new ArrayList<>();
            items.addAll(Arrays.asList(Item.values()));
            items.addAll(Arrays.asList(Item.values()));
            recyclerView.setAdapter(new BaseRecyclerAdapter<Item>(items, simple_list_item_2, this) {
                @Override
                protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) {
                    holder.text(android.R.id.text1, model.name());
                    holder.text(android.R.id.text2, model.nameId);
                    holder.textColorId(android.R.id.text2, R.color.colorTextAssistant);
                }
            });
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        switch (Item.values()[position % Item.values().length]) {
            case 內容不偏移:
                mRefreshLayout.setEnableHeaderTranslationContent(false);
                break;
            case 內容跟隨偏移:
                mRefreshLayout.setEnableHeaderTranslationContent(true);
                break;
            case 藍色主題:
                setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark);
                break;
            case 綠色主題:
                setThemeColor(android.R.color.holo_green_light, android.R.color.holo_green_dark);
                break;
            case 紅色主題:
                setThemeColor(android.R.color.holo_red_light, android.R.color.holo_red_dark);
                break;
            case 橙色主題:
                setThemeColor(android.R.color.holo_orange_light, android.R.color.holo_orange_dark);
                break;
        }
        mRefreshLayout.autoRefresh();
    }

    private void setThemeColor(int colorPrimary, int colorPrimaryDark) {
        mToolbar.setBackgroundResource(colorPrimary);
        mRefreshLayout.setPrimaryColorsId(colorPrimary, android.R.color.white);
        if (Build.VERSION.SDK_INT >= 21) {
            getWindow().setStatusBarColor(ContextCompat.getColor(this, colorPrimaryDark));
        }
    }
}
GIF.gif
public class BezierRadarStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    private enum Item {
        打開左右拖動(R.string.item_style_horizontal_drag_on),
        關閉左右拖動(R.string.item_style_horizontal_drag_off),
        內容不偏移(R.string.item_style_content_translation_off),
        內容跟隨偏移(R.string.item_style_content_translation_on),
        橙色主題(R.string.item_style_theme_orange_abstract),
        紅色主題(R.string.item_style_theme_red_abstract),
        綠色主題(R.string.item_style_theme_green_abstract),
        藍色主題(R.string.item_style_theme_blue_abstract),
        ;
        public int nameId;
        Item(@StringRes int nameId) {
            this.nameId = nameId;
        }
    }

    private Toolbar mToolbar;
    private RefreshLayout mRefreshLayout;
    private BezierRadarHeader mRefreshHeader;
    private static boolean isFirstEnter = true;

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

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        mRefreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);
        mRefreshHeader = (BezierRadarHeader) findViewById(R.id.header);
        if (isFirstEnter) {
            isFirstEnter = false;
            mRefreshLayout.autoRefresh();//第一次進入觸發自動刷新,演示效果
        }

        View view = findViewById(R.id.recyclerView);
        if (view instanceof RecyclerView) {
            RecyclerView recyclerView = (RecyclerView) view;
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL));
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            List<Item> items = new ArrayList<>();
            items.addAll(Arrays.asList(Item.values()));
            items.addAll(Arrays.asList(Item.values()));
            recyclerView.setAdapter(new BaseRecyclerAdapter<Item>(items, simple_list_item_2,this) {
                @Override
                protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) {
                    holder.text(android.R.id.text1, model.name());
                    holder.text(android.R.id.text2, model.nameId);
                    holder.textColorId(android.R.id.text2, R.color.colorTextAssistant);
                }
            });
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        switch (Item.values()[position % Item.values().length]) {
            case 內容不偏移:
                mRefreshLayout.setEnableHeaderTranslationContent(false);
                break;
            case 內容跟隨偏移:
                mRefreshLayout.setEnableHeaderTranslationContent(true);
                break;
            case 藍色主題:
                setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark);
                break;
            case 綠色主題:
                setThemeColor(android.R.color.holo_green_light, android.R.color.holo_green_dark);
                break;
            case 紅色主題:
                setThemeColor(android.R.color.holo_red_light, android.R.color.holo_red_dark);
                break;
            case 橙色主題:
                setThemeColor(android.R.color.holo_orange_light, android.R.color.holo_orange_dark);
                break;
            case 打開左右拖動:
                mRefreshHeader.setEnableHorizontalDrag(true);
                break;
            case 關閉左右拖動:
                mRefreshHeader.setEnableHorizontalDrag(false);
                break;
        }
        mRefreshLayout.autoRefresh();
    }

    private void setThemeColor(int colorPrimary, int colorPrimaryDark) {
        mToolbar.setBackgroundResource(colorPrimary);
        mRefreshLayout.setPrimaryColorsId(colorPrimary, android.R.color.white);
        if (Build.VERSION.SDK_INT >= 21) {
            getWindow().setStatusBarColor(ContextCompat.getColor(this, colorPrimaryDark));
        }
    }
}
GIF.gif
public class ClassicsStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    private BaseRecyclerAdapter<Item> mAdpater;

    private enum Item {
        尺寸拉伸(R.string.item_style_spinner_scale),
        位置平移(R.string.item_style_spinner_translation),
        背后固定(R.string.item_style_spinner_behind),
        顯示時間(R.string.item_style_spinner_update_on),
        隱藏時間(R.string.item_style_spinner_update_off),
//        加載更多(R.string.item_style_load_more),
        默認主題(R.string.item_style_theme_default_abstract),
        橙色主題(R.string.item_style_theme_orange_abstract),
        紅色主題(R.string.item_style_theme_red_abstract),
        綠色主題(R.string.item_style_theme_green_abstract),
        藍色主題(R.string.item_style_theme_blue_abstract),
        ;
        public int nameId;
        Item(@StringRes int nameId) {
            this.nameId = nameId;
        }
    }

    private Toolbar mToolbar;
    private RecyclerView mRecyclerView;
    private RefreshLayout mRefreshLayout;
    private ClassicsHeader mClassicsHeader;
    private static boolean isFirstEnter = true;

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

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        mRefreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);

        int delta = new Random().nextInt(7 * 24 * 60 * 60 * 1000);
        mClassicsHeader = (ClassicsHeader)mRefreshLayout.getRefreshHeader();
        mClassicsHeader.setLastUpdateTime(new Date(System.currentTimeMillis()-delta));
        mClassicsHeader.setTimeFormat(new SimpleDateFormat("更新于 MM-dd HH:mm", Locale.CHINA));
        mClassicsHeader.setTimeFormat(new SimpleDateFormat("更新于 MM-dd HH:mm", Locale.CHINA));
        View view = findViewById(R.id.recyclerView);
        if (view instanceof RecyclerView) {
            RecyclerView recyclerView = (RecyclerView) view;
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL));
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            List<Item> items = new ArrayList<>();
            items.addAll(Arrays.asList(Item.values()));
            items.addAll(Arrays.asList(Item.values()));
            recyclerView.setAdapter(mAdpater = new BaseRecyclerAdapter<Item>(items, simple_list_item_2,this) {
                @Override
                protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) {
                    holder.text(android.R.id.text1, model.name());
                    holder.text(android.R.id.text2, model.nameId);
                    holder.textColorId(android.R.id.text2, R.color.colorTextAssistant);
                }
            });
            mRecyclerView = recyclerView;
        }

        if (isFirstEnter) {
            isFirstEnter = false;
            //觸發自動刷新
            mRefreshLayout.autoRefresh();
        }

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        switch (Item.values()[position % Item.values().length]) {
            case 尺寸拉伸:
                mClassicsHeader.setSpinnerStyle(SpinnerStyle.Scale);
                break;
            case 位置平移:
                mClassicsHeader.setSpinnerStyle(SpinnerStyle.Translate);
                break;
            case 顯示時間:
                mClassicsHeader.setEnableLastTime(true);
                break;
            case 隱藏時間:
                mClassicsHeader.setEnableLastTime(false);
                break;
        }
        mRefreshLayout.autoRefresh();
    }
}
GIF.gif
public class DeliveryStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    private enum Item {
        默認主題(R.string.item_style_theme_default_abstract),
        橙色主題(R.string.item_style_theme_orange_abstract),
        紅色主題(R.string.item_style_theme_red_abstract),
        綠色主題(R.string.item_style_theme_green_abstract),
        藍色主題(R.string.item_style_theme_blue_abstract),
        ;
        public int nameId;
        Item(@StringRes int nameId) {
            this.nameId = nameId;
        }
    }

    private Toolbar mToolbar;
    private RefreshLayout mRefreshLayout;
    private static boolean isFirstEnter = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_style_delivery);
        if (Build.VERSION.SDK_INT >= 21) {
            getWindow().setStatusBarColor(0xfff0f0f0);
        }
        if (Build.VERSION.SDK_INT >= 23) {
            Window window = getWindow();
            int systemUiVisibility = window.getDecorView().getSystemUiVisibility();
            systemUiVisibility |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            window.getDecorView().setSystemUiVisibility(systemUiVisibility);
        }

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        mRefreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);
        if (isFirstEnter) {
            isFirstEnter = false;
            mRefreshLayout.autoRefresh();//第一次進入觸發自動刷新,演示效果
        }

        View view = findViewById(R.id.recyclerView);
        if (view instanceof RecyclerView) {
            RecyclerView recyclerView = (RecyclerView) view;
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            List<Item> items = new ArrayList<>();
            items.addAll(Arrays.asList(Item.values()));
            items.addAll(Arrays.asList(Item.values()));
            recyclerView.setAdapter(new BaseRecyclerAdapter<Item>(items, R.layout.item_style_delivery,this) {
                @Override
                protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) {
                }
            });
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        switch (Item.values()[position % Item.values().length]) {
            case 默認主題:
                mToolbar.setBackgroundResource(android.R.color.white);
                mToolbar.setTitleTextColor(0xffbbbbbb);
                mToolbar.setNavigationIcon(R.drawable.ic_arrow_back_gray_24dp);
                mRefreshLayout.setPrimaryColors(0xfff0f0f0, 0xffffffff);
                if (Build.VERSION.SDK_INT >= 21) {
                    getWindow().setStatusBarColor(0xfff0f0f0);
                }
                if (Build.VERSION.SDK_INT >= 23) {
                    Window window = getWindow();
                    int systemUiVisibility = window.getDecorView().getSystemUiVisibility();
                    systemUiVisibility |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
                    window.getDecorView().setSystemUiVisibility(systemUiVisibility);
                }
                break;
            case 藍色主題:
                setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark);
                break;
            case 綠色主題:
                setThemeColor(android.R.color.holo_green_light, android.R.color.holo_green_dark);
                break;
            case 紅色主題:
                setThemeColor(android.R.color.holo_red_light, android.R.color.holo_red_dark);
                break;
            case 橙色主題:
                setThemeColor(android.R.color.holo_orange_light, android.R.color.holo_orange_dark);
                break;
        }
        mRefreshLayout.autoRefresh();
    }

    private void setThemeColor(int colorPrimary, int colorPrimaryDark) {
        mToolbar.setBackgroundResource(colorPrimary);
        mToolbar.setTitleTextColor(ContextCompat.getColor(this, android.R.color.white));
        mToolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp);
        mRefreshLayout.setPrimaryColorsId(colorPrimary, android.R.color.white);
        if (Build.VERSION.SDK_INT >= 21) {
            getWindow().setStatusBarColor(ContextCompat.getColor(this, colorPrimaryDark));
        }
        if (Build.VERSION.SDK_INT >= 23) {
            Window window = getWindow();
            int systemUiVisibility = window.getDecorView().getSystemUiVisibility();
            systemUiVisibility &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            window.getDecorView().setSystemUiVisibility(systemUiVisibility);
        }
    }
}

GIF.gif
public class DropBoxStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    private enum Item {
        默認主題(R.string.item_style_theme_default_abstract),
        橙色主題(R.string.item_style_theme_orange_abstract),
        紅色主題(R.string.item_style_theme_red_abstract),
        綠色主題(R.string.item_style_theme_green_abstract),
        藍色主題(R.string.item_style_theme_blue_abstract),


        默認1主題(R.string.item_style_theme_default_abstract),
        橙色1主題(R.string.item_style_theme_orange_abstract),
        紅色1主題(R.string.item_style_theme_red_abstract),
        綠色1主題(R.string.item_style_theme_green_abstract),
        藍色1主題(R.string.item_style_theme_blue_abstract),


        默認2主題(R.string.item_style_theme_default_abstract),
        橙色2主題(R.string.item_style_theme_orange_abstract),
        紅色2主題(R.string.item_style_theme_red_abstract),
        綠色2主題(R.string.item_style_theme_green_abstract),
        藍色2主題(R.string.item_style_theme_blue_abstract),
        ;
        public int nameId;
        Item(@StringRes int nameId) {
            this.nameId = nameId;
        }
    }

    private Toolbar mToolbar;
    private RefreshLayout mRefreshLayout;
    private static boolean isFirstEnter = true;

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

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        mRefreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);
        if (isFirstEnter) {
            isFirstEnter = false;
            mRefreshLayout.autoRefresh();//第一次進入觸發自動刷新,演示效果
        }

        View view = findViewById(R.id.recyclerView);
        if (view instanceof RecyclerView) {
            RecyclerView recyclerView = (RecyclerView) view;
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL));
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            recyclerView.setAdapter(new BaseRecyclerAdapter<Item>(Arrays.asList(Item.values()), simple_list_item_2,this) {
                @Override
                protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) {
                    holder.text(android.R.id.text1, model.name());
                    holder.text(android.R.id.text2, model.nameId);
                    holder.textColorId(android.R.id.text2, R.color.colorTextAssistant);
                }
            });
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        switch (Item.values()[position % Item.values().length]) {
            case 默認主題:
                setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark);
                mRefreshLayout.setPrimaryColors(0xff283645, 0xff6ea9ff);
                break;
            case 藍色主題:
                setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark);
                break;
            case 綠色主題:
                setThemeColor(android.R.color.holo_green_light, android.R.color.holo_green_dark);
                break;
            case 紅色主題:
                setThemeColor(android.R.color.holo_red_light, android.R.color.holo_red_dark);
                break;
            case 橙色主題:
                setThemeColor(android.R.color.holo_orange_light, android.R.color.holo_orange_dark);
                break;
        }
        mRefreshLayout.autoRefresh();
    }

    private void setThemeColor(int colorPrimary, int colorPrimaryDark) {
        mToolbar.setBackgroundResource(colorPrimary);
        mRefreshLayout.setPrimaryColorsId(colorPrimary, android.R.color.white);
        if (Build.VERSION.SDK_INT >= 21) {
            getWindow().setStatusBarColor(ContextCompat.getColor(this, colorPrimaryDark));
        }
    }
}

GIF.gif
public class FlyRefreshStyleActivity extends AppCompatActivity {

    private RecyclerView mListView;
    private RefreshLayout mRefreshLayout;

    private ItemAdapter mAdapter;

    private FlyView mFlyView;
    private ArrayList<ItemData> mDataSet = new ArrayList<>();
    private LinearLayoutManager mLayoutManager;
    private FlyRefreshHeader mFlyRefreshHeader;
    private CollapsingToolbarLayout mToolbarLayout;
    private FloatingActionButton mActionButton;
    private View.OnClickListener mThemeListener;
    private static boolean isFirstEnter = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fly_refresh);
//        final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
//        setSupportActionBar(toolbar);
//        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                finish();
//            }
//        });

        /*-----------------------------------------------------------
         * 關鍵代碼-開始
         *----------------------------------------------------------*/

        MountainSceneView mSceneView = (MountainSceneView) findViewById(R.id.mountain);
        mFlyView = (FlyView) findViewById(R.id.flyView);
        mFlyRefreshHeader = (FlyRefreshHeader) findViewById(R.id.flyRefresh);
        mFlyRefreshHeader.setUp(mSceneView, mFlyView);//綁定場景和紙飛機
        mRefreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);
        mRefreshLayout.setReboundInterpolator(new ElasticOutInterpolator());//設置回彈插值器,會帶有彈簧震動效果
        mRefreshLayout.setReboundDuration(800);//設置回彈動畫時長
        mRefreshLayout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                View child = mListView.getChildAt(0);
                if (child != null) {
                    //開始刷新的時候個第一個item設置動畫效果
                    bounceAnimateView(child.findViewById(R.id.icon));
                }
                updateTheme();//改變主題顏色
                mRefreshLayout.getLayout().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //通知刷新完成,這里改為通知Header,讓紙飛機飛回來
                        mFlyRefreshHeader.finishRefresh(new AnimatorListenerAdapter() {
                            public void onAnimationEnd(Animator animation) {
                                addItemData();//在紙飛機回到原位之后添加數據效果更真實
                            }
                        });
                    }
                }, 2000);//模擬兩秒的后臺數據加載
            }
        });
        //設置 讓 AppBarLayout 和 RefreshLayout 的滾動同步 并不保持 toolbar 位置不變
        final AppBarLayout appBar = (AppBarLayout) findViewById(R.id.appbar);
        mRefreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() {
            @Override
            public void onHeaderMoving(RefreshHeader header, boolean isDragging, float percent, int offset, int headerHeight, int maxDragHeight) {
                appBar.setTranslationY(offset);
//                toolbar.setTranslationY(-offset);
            }
//            @Override
//            public void onHeaderPulling(@NonNull RefreshHeader header, float percent, int offset, int footerHeight, int maxDragHeight) {
//                appBar.setTranslationY(offset);
//                toolbar.setTranslationY(-offset);
//            }
//            @Override
//            public void onHeaderReleasing(@NonNull RefreshHeader header, float percent, int offset, int footerHeight, int maxDragHeight) {
//                appBar.setTranslationY(offset);
//                toolbar.setTranslationY(-offset);
//            }
        });
        /*-----------------------------------------------------------
         * 關鍵代碼-結束
         *----------------------------------------------------------*/

        if (isFirstEnter) {
            isFirstEnter = false;
            mRefreshLayout.autoRefresh();//第一次進入觸發自動刷新,演示效果
        }

        /*
         * 初始化列表數據
         */
        initDataSet();
        mAdapter = new ItemAdapter(this);
        mLayoutManager = new LinearLayoutManager(this);
        mListView = (RecyclerView) findViewById(R.id.recyclerView);
        mListView.setLayoutManager(mLayoutManager);
        mListView.setAdapter(mAdapter);
        mToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.toolbarLayout);
        mActionButton = (FloatingActionButton) findViewById(R.id.fab);
        /*
         * 設置點擊 ActionButton 時候觸發自動刷新 并改變主題顏色
         */
        mActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateTheme();
                mRefreshLayout.autoRefresh();
            }
        });
        /*
         * 監聽 AppBarLayout 的關閉和開啟 給 FlyView(紙飛機) 和 ActionButton 設置關閉隱藏動畫
         */
        appBar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            boolean misAppbarExpand = true;
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                int scrollRange = appBarLayout.getTotalScrollRange();
                float fraction = 1f * (scrollRange + verticalOffset) / scrollRange;
                if (fraction < 0.1 && misAppbarExpand) {
                    misAppbarExpand = false;
                    mActionButton.animate().scaleX(0).scaleY(0);
                    mFlyView.animate().scaleX(0).scaleY(0);
                    ValueAnimator animator = ValueAnimator.ofInt(mListView.getPaddingTop(), 0);
                    animator.setDuration(300);
                    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(ValueAnimator animation) {
                            mListView.setPadding(0, (int) animation.getAnimatedValue(), 0, 0);
                        }
                    });
                    animator.start();
                }
                if (fraction > 0.8 && !misAppbarExpand) {
                    misAppbarExpand = true;
                    mActionButton.animate().scaleX(1).scaleY(1);
                    mFlyView.animate().scaleX(1).scaleY(1);
                    ValueAnimator animator = ValueAnimator.ofInt(mListView.getPaddingTop(), DensityUtil.dp2px(25));
                    animator.setDuration(300);
                    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(ValueAnimator animation) {
                            mListView.setPadding(0, (int) animation.getAnimatedValue(), 0, 0);
                        }
                    });
                    animator.start();
                }
            }
        });
    }

    private void updateTheme() {
        if (mThemeListener == null) {
            mThemeListener = new View.OnClickListener() {
                int index = 0;
                int[] ids = new int[]{
                        R.color.colorPrimary,
                        android.R.color.holo_green_light,
                        android.R.color.holo_red_light,
                        android.R.color.holo_orange_light,
                        android.R.color.holo_blue_bright,
                };
                @Override
                public void onClick(View v) {
                    int color = ContextCompat.getColor(getApplication(), ids[index % ids.length]);
                    mRefreshLayout.setPrimaryColors(color);
                    mActionButton.setBackgroundColor(color);
                    mActionButton.setBackgroundTintList(ColorStateList.valueOf(color));
                    mToolbarLayout.setContentScrimColor(color);
                    index++;
                }
            };
        }
        mThemeListener.onClick(null);
    }

    private void initDataSet() {
        try {
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
            mDataSet.add(new ItemData(0xFF76A9FC, R.drawable.ic_fly_refresh_poll, "Meeting Minutes", format.parse("2014-03-09")));
            mDataSet.add(new ItemData(Color.GRAY, R.drawable.ic_fly_refresh_folder, "Favorites Photos", format.parse("2014-02-03")));
            mDataSet.add(new ItemData(Color.GRAY, R.drawable.ic_fly_refresh_folder, "Photos", format.parse("2014-01-09")));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    private void addItemData() {
        ItemData itemData = new ItemData(0xFFFFC970, R.drawable.ic_fly_refresh_smartphone, "Magic Cube Show", new Date());
        mDataSet.add(0, itemData);
        mAdapter.notifyItemInserted(0);
        mLayoutManager.scrollToPosition(0);
    }

    private void bounceAnimateView(final View view) {
        if (view == null) {
            return;
        }

        ValueAnimator swing = ValueAnimator.ofFloat(0, 60, -40, 0);
        swing.setDuration(400);
        swing.setInterpolator(new AccelerateInterpolator());
        swing.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                view.setRotationX((float)animation.getAnimatedValue());
            }
        });
        swing.start();
    }

    private class ItemAdapter extends RecyclerView.Adapter<ItemViewHolder> {

        private LayoutInflater mInflater;
        private DateFormat dateFormat;

        ItemAdapter(Context context) {
            mInflater = LayoutInflater.from(context);
            dateFormat = SimpleDateFormat.getDateInstance(DateFormat.DEFAULT, Locale.ENGLISH);
        }

        @NonNull
        @Override
        public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            View view = mInflater.inflate(R.layout.activity_fly_refresh_item, viewGroup, false);
            return new ItemViewHolder(view);
        }

        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
        @Override
        public void onBindViewHolder(@NonNull ItemViewHolder itemViewHolder, int i) {
            final ItemData data = mDataSet.get(i);
            ShapeDrawable drawable = new ShapeDrawable(new OvalShape());
            drawable.getPaint().setColor(data.color);
            itemViewHolder.icon.setBackground(drawable);
            itemViewHolder.icon.setImageResource(data.icon);
            itemViewHolder.title.setText(data.title);
            itemViewHolder.subTitle.setText(dateFormat.format(data.time));
        }

        @Override
        public int getItemCount() {
            return mDataSet.size();
        }
    }

    private static class ItemViewHolder extends RecyclerView.ViewHolder {

        ImageView icon;
        TextView title;
        TextView subTitle;

        ItemViewHolder(View itemView) {
            super(itemView);
            icon = (ImageView) itemView.findViewById(R.id.icon);
            title = (TextView) itemView.findViewById(R.id.title);
            subTitle = (TextView) itemView.findViewById(R.id.subtitle);
        }

    }
    public class ItemData {
        int color;
        int icon;
        Date time;
        public String title;

        ItemData(int color, int icon, String title, Date time) {
            this.color = color;
            this.icon = icon;
            this.title = title;
            this.time = time;
        }
    }
    public class ElasticOutInterpolator implements Interpolator {

        @Override
        public float getInterpolation(float t) {
            if (t == 0) return 0;
            if (t >= 1) return 1;
            float p=.3f;
            float s=p/4;
            return ((float)Math.pow(2,-10*t) * (float)Math.sin( (t-s)*(2*(float)Math.PI)/p) + 1);
        }
    }

}

GIF.gif
public class FunGameBattleCityStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    private enum Item {
        默認主題(R.string.item_style_theme_default_abstract),
        橙色主題(R.string.item_style_theme_orange_abstract),
        紅色主題(R.string.item_style_theme_red_abstract),
        綠色主題(R.string.item_style_theme_green_abstract),
        藍色主題(R.string.item_style_theme_blue_abstract),
        ;
        public int nameId;
        Item(@StringRes int nameId) {
            this.nameId = nameId;
        }
    }

    private Toolbar mToolbar;
    private RefreshLayout mRefreshLayout;
    private static boolean isFirstEnter = true;

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

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        mRefreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);
        if (isFirstEnter) {
            isFirstEnter = false;
            mRefreshLayout.autoRefresh();//第一次進入觸發自動刷新,演示效果
        }

        View view = findViewById(R.id.recyclerView);
        if (view instanceof RecyclerView) {
            RecyclerView recyclerView = (RecyclerView) view;
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL));
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            List<Item> items = new ArrayList<>();
            items.addAll(Arrays.asList(Item.values()));
            items.addAll(Arrays.asList(Item.values()));
            items.addAll(Arrays.asList(Item.values()));
            recyclerView.setAdapter(new BaseRecyclerAdapter<Item>(items, simple_list_item_2,this) {
                @Override
                protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) {
                    holder.text(android.R.id.text1, model.name());
                    holder.text(android.R.id.text2, model.nameId);
                    holder.textColorId(android.R.id.text2, R.color.colorTextAssistant);
                }
            });
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        switch (Item.values()[position % Item.values().length]) {
            case 默認主題:
                mRefreshLayout.setPrimaryColorsId(android.R.color.white, android.R.color.black);
                break;
            case 藍色主題:
                setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark);
                break;
            case 綠色主題:
                setThemeColor(android.R.color.holo_green_light, android.R.color.holo_green_dark);
                break;
            case 紅色主題:
                setThemeColor(android.R.color.holo_red_light, android.R.color.holo_red_dark);
                break;
            case 橙色主題:
                setThemeColor(android.R.color.holo_orange_light, android.R.color.holo_orange_dark);
                break;
        }
        mRefreshLayout.autoRefresh();
    }

    private void setThemeColor(int colorPrimary, int colorPrimaryDark) {
        mToolbar.setBackgroundResource(colorPrimary);
        mRefreshLayout.setPrimaryColorsId(colorPrimary, android.R.color.white);
        if (Build.VERSION.SDK_INT >= 21) {
            getWindow().setStatusBarColor(ContextCompat.getColor(this, colorPrimaryDark));
        }
    }
}

GIF.gif
public class FunGameHitBlockStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    private enum Item {
        默認主題(R.string.item_style_theme_default_abstract),
        橙色主題(R.string.item_style_theme_orange_abstract),
        紅色主題(R.string.item_style_theme_red_abstract),
        綠色主題(R.string.item_style_theme_green_abstract),
        藍色主題(R.string.item_style_theme_blue_abstract),
        ;
        public int nameId;
        Item(@StringRes int nameId) {
            this.nameId = nameId;
        }
    }

    private Toolbar mToolbar;
    private RefreshLayout mRefreshLayout;
    private static boolean isFirstEnter = true;

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

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        mRefreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);
        if (isFirstEnter) {
            isFirstEnter = false;
            mRefreshLayout.autoRefresh();//第一次進入觸發自動刷新,演示效果
        }

        View view = findViewById(R.id.recyclerView);
        if (view instanceof RecyclerView) {
            RecyclerView recyclerView = (RecyclerView) view;
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL));
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            List<Item> items = new ArrayList<>();
            items.addAll(Arrays.asList(Item.values()));
            items.addAll(Arrays.asList(Item.values()));
            items.addAll(Arrays.asList(Item.values()));
            recyclerView.setAdapter(new BaseRecyclerAdapter<Item>(items, simple_list_item_2,this) {
                @Override
                protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) {
                    holder.text(android.R.id.text1, model.name());
                    holder.text(android.R.id.text2, model.nameId);
                    holder.textColorId(android.R.id.text2, R.color.colorTextAssistant);
                }
            });
        }

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        switch (Item.values()[position % Item.values().length]) {
            case 默認主題:
                mRefreshLayout.setPrimaryColorsId(android.R.color.white, android.R.color.black);
                break;
            case 藍色主題:
                setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark);
                break;
            case 綠色主題:
                setThemeColor(android.R.color.holo_green_light, android.R.color.holo_green_dark);
                break;
            case 紅色主題:
                setThemeColor(android.R.color.holo_red_light, android.R.color.holo_red_dark);
                break;
            case 橙色主題:
                setThemeColor(android.R.color.holo_orange_light, android.R.color.holo_orange_dark);
                break;
        }
        mRefreshLayout.autoRefresh();
    }

    private void setThemeColor(int colorPrimary, int colorPrimaryDark) {
        mToolbar.setBackgroundResource(colorPrimary);
        mRefreshLayout.setPrimaryColorsId(colorPrimary, android.R.color.white);
        if (Build.VERSION.SDK_INT >= 21) {
            getWindow().setStatusBarColor(ContextCompat.getColor(this, colorPrimaryDark));
        }
    }
}

Android智能下拉刷新、上拉加載框架(二)——SmartRefreshLayout
Android智能下拉刷新、上拉加載框架(三)——SmartRefreshLayout
源碼地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容