Android自定義下拉刷新動畫--仿百度外賣下拉刷新

好久沒寫博客了活孩,小編之前一段時間一直在找工作物遇,從天津來到了我們的大帝都,感覺還不錯。好了廢話不多說了询兴,開始我們今天的主題吧∧松常現(xiàn)如今的APP各式各樣,同樣也帶來了各種需求诗舰,一個下拉刷新都能玩出花樣了警儒,前兩天訂飯的時候不經(jīng)意間看到了“百度外賣”的下拉刷新,今天的主題就是它--自定義下拉刷新動畫始衅。

看一下實現(xiàn)效果吧:

20160411115612150.gif

動畫

我們先來看看Android中的動畫吧:
Android中的動畫分為三種:

  • Tween動畫冷蚂,這一類的動畫提供了旋轉、平移汛闸、縮放等效果蝙茶。
    • Alpha -- 淡入淡出
    • Scale -- 縮放效果
    • Roate -- 旋轉效果
    • Translate -- 平移效果
  • Frame動畫(幀動畫),這一類動畫可以創(chuàng)建一個Drawable序列诸老,按照指定時間間歇一個一個顯示出來隆夯。
  • Property動畫(屬性動畫),Android3.0之后引入出來的屬性動畫别伏,它更改的是對象的實際屬性蹄衷。

分析

這里寫圖片描述

我們可以看到百度外賣的下拉刷新的頭是一個騎車的快遞員在路上疾行,分析一下我們得到下面的動畫:

  1. 背景圖片的平移動畫
  2. 太陽的自旋轉動畫
  3. 兩個小輪子的自旋轉動畫

這就很簡單了厘肮,接下來我們去百度外面的圖片資源文件里找到這幾張圖片:(下載百度外賣的apk直接解壓即可)


這里寫圖片描述

定義下拉刷新頭文件:headview.xml

這里注意一下:我們定義了兩張背景圖片的ImageView是為了可以實現(xiàn)背景的平移動畫效果愧口。

這里寫圖片描述
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">


    <ImageView
        android:id="@+id/iv_back1"
        android:src="@drawable/pull_back"
        android:layout_width="match_parent"
        android:layout_height="100dp" />
    <ImageView
        android:id="@+id/iv_back2"
        android:src="@drawable/pull_back"
        android:layout_width="match_parent"
        android:layout_height="100dp" />

    <RelativeLayout
        android:id="@+id/main"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <ImageView
            android:layout_marginTop="45dp"
            android:id="@+id/iv_rider"
            android:background="@drawable/pull_rider"
            android:layout_width="50dp"
            android:layout_height="50dp" />
        <ImageView
            android:id="@+id/wheel1"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="90dp"
            android:background="@drawable/pull_wheel"
            android:layout_width="15dp"
            android:layout_height="15dp" />
        <ImageView
            android:id="@+id/wheel2"
            android:layout_marginLeft="40dp"
            android:layout_marginTop="90dp"
            android:background="@drawable/pull_wheel"
            android:layout_width="15dp"
            android:layout_height="15dp" />
    </RelativeLayout>
    <ImageView
        android:id="@+id/ivsun"
        android:layout_marginTop="20dp"
        android:layout_toRightOf="@+id/main"
        android:background="@drawable/pull_sun"
        android:layout_width="30dp"
        android:layout_height="30dp" />

</RelativeLayout>

接下來我們定義動畫效果:

背景圖片的平移效果:
實現(xiàn)兩個animation xml文件,一個起始位置在100%类茂,結束位置在0%耍属,設置repeat屬性為循環(huán)往復。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
    <translate android:fromXDelta="100%p" android:toXDelta="0%p"
        android:repeatMode="restart"
        android:interpolator="@android:anim/linear_interpolator"
        android:repeatCount="infinite"
        android:duration="5000" />
</set>

另一個起始位置在0%巩检,結束位置在-100%

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
    <translate android:fromXDelta="0%p" android:toXDelta="-100%p"
        android:repeatMode="restart"
        android:interpolator="@android:anim/linear_interpolator"
        android:repeatCount="infinite"
        android:duration="5000" />
</set>

太陽圍繞中心旋轉動畫:
從0-360度開始循環(huán)旋轉厚骗,旋轉所用時間為1s,旋轉中心距離view的左定點上邊緣為50%的距離兢哭,也就是正中心领舰。

下面是具體屬性:

android:fromDegrees 起始的角度度數(shù)

android:toDegrees 結束的角度度數(shù),負數(shù)表示逆時針迟螺,正數(shù)表示順時針冲秽。如10圈則比android:fromDegrees大3600即可

android:pivotX 旋轉中心的X坐標

浮點數(shù)或是百分比。浮點數(shù)表示相對于Object的左邊緣煮仇,如5; 百分比表示相對于Object的左邊緣劳跃,如5%; 另一種百分比表示相對于父容器的左邊緣,如5%p; 一般設置為50%表示在Object中心

android:pivotY 旋轉中心的Y坐標

浮點數(shù)或是百分比浙垫。浮點數(shù)表示相對于Object的上邊緣,如5; 百分比表示相對于Object的上邊緣,如5%; 另一種百分比表示相對于父容器的上邊緣夹姥,如5%p; 一般設置為50%表示在Object中心

android:duration 表示從android:fromDegrees轉動到android:toDegrees所花費的時間杉武,單位為毫秒≌奘郏可以用來計算速度轻抱。

android:interpolator表示變化率,但不是運行速度旦部。一個插補屬性祈搜,可以將動畫效果設置為加速,減速士八,反復容燕,反彈等。默認為開始和結束慢中間快婚度,

android:startOffset 在調用start函數(shù)之后等待開始運行的時間蘸秘,單位為毫秒,若為10蝗茁,表示10ms后開始運行

android:repeatCount 重復的次數(shù)醋虏,默認為0,必須是int哮翘,可以為-1表示不停止

android:repeatMode 重復的模式颈嚼,默認為restart,即重頭開始重新運行饭寺,可以為reverse即從結束開始向前重新運行阻课。在android:repeatCount大于0或為infinite時生效

android:detachWallpaper 表示是否在壁紙上運行

android:zAdjustment 表示被animated的內容在運行時在z軸上的位置,默認為normal佩研。

normal保持內容當前的z軸順序

top運行時在最頂層顯示

bottom運行時在最底層顯示

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:fromDegrees="0"
        android:toDegrees="360"
        android:duration="1000"
        android:repeatCount="-1"
        android:pivotX="50%"
        android:pivotY="50%" />
</set>

同理輪子的動畫也一樣柑肴,不占代碼了。

動畫定義完了我們開始定義下拉刷新列表旬薯,下拉刷新網(wǎng)上有很多晰骑,不詳細的說了,簡單的改造一下绊序,根據(jù)刷新狀態(tài)開啟關閉動畫即可硕舆。
注釋寫的很詳細,看一下代碼吧:

package com.hankkin.baidugoingrefreshlayout;

import android.widget.AbsListView;
import android.widget.ListView;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.RelativeLayout;

/**
 * Created by Hankkin on 16/4/10.
 */
public class BaiDuRefreshListView extends ListView implements AbsListView.OnScrollListener{
    private static final int DONE = 0;      //刷新完畢狀態(tài)
    private static final int PULL_TO_REFRESH = 1;   //下拉刷新狀態(tài)
    private static final int RELEASE_TO_REFRESH = 2;    //釋放狀態(tài)
    private static final int REFRESHING = 3;    //正在刷新狀態(tài)
    private static final int RATIO = 3;
    private RelativeLayout headView;    //下拉刷新頭
    private int headViewHeight; //頭高度
    private float startY;   //開始Y坐標
    private float offsetY;  //Y軸偏移量
    private OnBaiduRefreshListener mOnRefreshListener;  //刷新接口
    private int state;  //狀態(tài)值
    private int mFirstVisibleItem;  //第一項可見item索引
    private boolean isRecord;   //是否記錄
    private boolean isEnd;  //是否結束
    private boolean isRefreable;    //是否刷新

    private ImageView ivWheel1,ivWheel2;    //輪組圖片組件
    private ImageView ivRider;  //騎手圖片組件
    private ImageView ivSun,ivBack1,ivBack2;    //太陽骤公、背景圖片1抚官、背景圖片2
    private Animation wheelAnimation,sunAnimation;  //輪子、太陽動畫
    private Animation backAnimation1,backAnimation2;    //兩張背景圖動畫

    public BaiDuRefreshListView(Context context) {
        super(context);
        init(context);
    }

    public BaiDuRefreshListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public BaiDuRefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public interface OnBaiduRefreshListener{
        void onRefresh();
    }

    /**
     * 回調接口阶捆,想實現(xiàn)下拉刷新的listview實現(xiàn)此接口
     * @param onRefreshListener
     */
    public void setOnBaiduRefreshListener(OnBaiduRefreshListener onRefreshListener){
        mOnRefreshListener = onRefreshListener;
        isRefreable = true;
    }

    /**
     * 刷新完畢凌节,從主線程發(fā)送過來钦听,并且改變headerView的狀態(tài)和文字動畫信息
     */
    public void setOnRefreshComplete(){
        //一定要將isEnd設置為true,以便于下次的下拉刷新
        isEnd = true;
        state = DONE;

        changeHeaderByState(state);
    }

    private void init(Context context) {
        //關閉view的OverScroll
        setOverScrollMode(OVER_SCROLL_NEVER);
        setOnScrollListener(this);
        //加載頭布局
        headView = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.headview,this,false);
        //測量頭布局
        measureView(headView);
        //給ListView添加頭布局
        addHeaderView(headView);
        //設置頭文件隱藏在ListView的第一項
        headViewHeight = headView.getMeasuredHeight();
        headView.setPadding(0, -headViewHeight, 0, 0);

        //獲取頭布局圖片組件
        ivRider = (ImageView) headView.findViewById(R.id.iv_rider);
        ivSun = (ImageView) headView.findViewById(R.id.ivsun);
        ivWheel1 = (ImageView) headView.findViewById(R.id.wheel1);
        ivWheel2 = (ImageView) headView.findViewById(R.id.wheel2);
        ivBack1 = (ImageView) headView.findViewById(R.id.iv_back1);
        ivBack2 = (ImageView) headView.findViewById(R.id.iv_back2);
        //獲取動畫
        wheelAnimation = AnimationUtils.loadAnimation(context, R.anim.tip);
        sunAnimation = AnimationUtils.loadAnimation(context, R.anim.tip1);

        backAnimation1 = AnimationUtils.loadAnimation(context, R.anim.a);
        backAnimation2 = AnimationUtils.loadAnimation(context, R.anim.b);

        state = DONE;
        isEnd = true;
        isRefreable = false;


    }

    @Override
    public void onScrollStateChanged(AbsListView absListView, int i) {
    }
    @Override
    public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        mFirstVisibleItem = firstVisibleItem;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isEnd) {//如果現(xiàn)在時結束的狀態(tài)倍奢,即刷新完畢了朴上,可以再次刷新了,在onRefreshComplete中設置
            if (isRefreable) {//如果現(xiàn)在是可刷新狀態(tài)   在setOnMeiTuanListener中設置為true
                switch (ev.getAction()){
                    //用戶按下
                    case MotionEvent.ACTION_DOWN:
                        //如果當前是在listview頂部并且沒有記錄y坐標
                        if (mFirstVisibleItem == 0 && !isRecord) {
                            //將isRecord置為true卒煞,說明現(xiàn)在已記錄y坐標
                            isRecord = true;
                            //將當前y坐標賦值給startY起始y坐標
                            startY = ev.getY();
                        }
                        break;
                    //用戶滑動
                    case MotionEvent.ACTION_MOVE:
                        //再次得到y(tǒng)坐標痪宰,用來和startY相減來計算offsetY位移值
                        float tempY = ev.getY();
                        //再起判斷一下是否為listview頂部并且沒有記錄y坐標
                        if (mFirstVisibleItem == 0 && !isRecord) {
                            isRecord = true;
                            startY = tempY;
                        }
                        //如果當前狀態(tài)不是正在刷新的狀態(tài),并且已經(jīng)記錄了y坐標
                        if (state!=REFRESHING && isRecord ) {
                            //計算y的偏移量
                            offsetY = tempY - startY;
                            //計算當前滑動的高度
                            float currentHeight = (-headViewHeight+offsetY/3);
                            //用當前滑動的高度和頭部headerView的總高度進行比 計算出當前滑動的百分比 0到1
                            float currentProgress = 1+currentHeight/headViewHeight;
                            //如果當前百分比大于1了畔裕,將其設置為1衣撬,目的是讓第一個狀態(tài)的橢圓不再繼續(xù)變大
                            if (currentProgress>=1) {
                                currentProgress = 1;
                            }
                            //如果當前的狀態(tài)是放開刷新,并且已經(jīng)記錄y坐標
                            if (state == RELEASE_TO_REFRESH && isRecord) {

                                setSelection(0);
                                //如果當前滑動的距離小于headerView的總高度
                                if (-headViewHeight+offsetY/RATIO<0) {
                                    //將狀態(tài)置為下拉刷新狀態(tài)
                                    state = PULL_TO_REFRESH;
                                    //根據(jù)狀態(tài)改變headerView扮饶,主要是更新動畫和文字等信息
                                    changeHeaderByState(state);
                                    //如果當前y的位移值小于0具练,即為headerView隱藏了
                                }else if (offsetY<=0) {
                                    //將狀態(tài)變?yōu)閐one
                                    state = DONE;
                                    stopAnim();
                                    //根據(jù)狀態(tài)改變headerView,主要是更新動畫和文字等信息
                                    changeHeaderByState(state);
                                }
                            }
                            //如果當前狀態(tài)為下拉刷新并且已經(jīng)記錄y坐標
                            if (state == PULL_TO_REFRESH && isRecord) {
                                setSelection(0);
                                //如果下拉距離大于等于headerView的總高度
                                if (-headViewHeight+offsetY/RATIO>=0) {
                                    //將狀態(tài)變?yōu)榉砰_刷新
                                    state = RELEASE_TO_REFRESH;
                                    //根據(jù)狀態(tài)改變headerView贴届,主要是更新動畫和文字等信息
                                    changeHeaderByState(state);
                                    //如果當前y的位移值小于0靠粪,即為headerView隱藏了
                                }else if (offsetY<=0) {
                                    //將狀態(tài)變?yōu)閐one
                                    state = DONE;
                                    //根據(jù)狀態(tài)改變headerView,主要是更新動畫和文字等信息
                                    changeHeaderByState(state);
                                }
                            }
                            //如果當前狀態(tài)為done并且已經(jīng)記錄y坐標
                            if (state == DONE && isRecord) {
                                //如果位移值大于0
                                if (offsetY>=0) {
                                    //將狀態(tài)改為下拉刷新狀態(tài)
                                    state = PULL_TO_REFRESH;
                                    changeHeaderByState(state);
                                }
                            }
                            //如果為下拉刷新狀態(tài)
                            if (state == PULL_TO_REFRESH) {
                                //則改變headerView的padding來實現(xiàn)下拉的效果
                                headView.setPadding(0,(int)(-headViewHeight+offsetY/RATIO) ,0,0);
                            }
                            //如果為放開刷新狀態(tài)
                            if (state == RELEASE_TO_REFRESH) {
                                //改變headerView的padding值
                                headView.setPadding(0,(int)(-headViewHeight+offsetY/RATIO) ,0, 0);
                            }
                        }
                        break;
                    //當用戶手指抬起時
                    case MotionEvent.ACTION_UP:
                        //如果當前狀態(tài)為下拉刷新狀態(tài)
                        if (state == PULL_TO_REFRESH) {
                            //平滑的隱藏headerView
                            this.smoothScrollBy((int)(-headViewHeight+offsetY/RATIO)+headViewHeight, 500);
                            //根據(jù)狀態(tài)改變headerView
                            changeHeaderByState(state);
                        }
                        //如果當前狀態(tài)為放開刷新
                        if (state == RELEASE_TO_REFRESH) {
                            //平滑的滑到正好顯示headerView
                            this.smoothScrollBy((int)(-headViewHeight+offsetY/RATIO), 500);
                            //將當前狀態(tài)設置為正在刷新
                            state = REFRESHING;
                            //回調接口的onRefresh方法
                            mOnRefreshListener.onRefresh();
                            //根據(jù)狀態(tài)改變headerView
                            changeHeaderByState(state);
                        }
                        //這一套手勢執(zhí)行完毫蚓,一定別忘了將記錄y坐標的isRecord改為false占键,以便于下一次手勢的執(zhí)行
                        isRecord = false;
                        break;
                }

            }
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 根據(jù)狀態(tài)改變headerView的動畫和文字顯示
     * @param state
     */
    private void changeHeaderByState(int state){
        switch (state) {
            case DONE://如果的隱藏的狀態(tài)
                //設置headerView的padding為隱藏
                headView.setPadding(0, -headViewHeight, 0, 0);
                startAnim();
                break;
            case RELEASE_TO_REFRESH://當前狀態(tài)為放開刷新
                break;
            case PULL_TO_REFRESH://當前狀態(tài)為下拉刷新
                startAnim();
                break;
            case REFRESHING://當前狀態(tài)為正在刷新
                break;
            default:
                break;
        }
    }

    /**
     * 測量View
     * @param child
     */
    private void measureView(View child) {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
                    MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0,
                    MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }

    /**
     * 開啟動畫
     */
    public void startAnim(){
        ivBack1.startAnimation(backAnimation1);
        ivBack2.startAnimation(backAnimation2);
        ivSun.startAnimation(sunAnimation);
        ivWheel1.startAnimation(wheelAnimation);
        ivWheel2.startAnimation(wheelAnimation);
    }

    /**
     * 關閉動畫
     */
    public void stopAnim(){
        ivBack1.clearAnimation();
        ivBack2.clearAnimation();
        ivSun.clearAnimation();
        ivWheel1.clearAnimation();
        ivWheel2.clearAnimation();
    }
}

好了,自定義下拉刷新動畫我們就實現(xiàn)了元潘,其實很簡單畔乙,所有的下拉刷新動畫都類似這樣實現(xiàn)的。源碼我已經(jīng)上傳到Github上了:
https://github.com/Hankkin/BaiduGoingRefreshLayout
求star啊翩概。有不合理的地方還希望大家多多指正牲距,共同進步哈。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末钥庇,一起剝皮案震驚了整個濱河市牍鞠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌评姨,老刑警劉巖难述,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吐句,居然都是意外死亡胁后,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門嗦枢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來攀芯,“玉大人,你說我怎么就攤上這事文虏÷屡担” “怎么了殖演?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長紧武。 經(jīng)常有香客問我剃氧,道長敏储,這世上最難降的妖魔是什么阻星? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮已添,結果婚禮上妥箕,老公的妹妹穿的比我還像新娘。我一直安慰自己更舞,他們只是感情好畦幢,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缆蝉,像睡著了一般宇葱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上刊头,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天黍瞧,我揣著相機與錄音,去河邊找鬼原杂。 笑死印颤,一個胖子當著我的面吹牛,可吹牛的內容都是我干的穿肄。 我是一名探鬼主播年局,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咸产!你這毒婦竟也來了矢否?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤脑溢,失蹤者是張志新(化名)和其女友劉穎僵朗,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體焚志,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡衣迷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了酱酬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片壶谒。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖膳沽,靈堂內的尸體忽然破棺而出汗菜,到底是詐尸還是另有隱情让禀,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布陨界,位于F島的核電站巡揍,受9級特大地震影響,放射性物質發(fā)生泄漏菌瘪。R本人自食惡果不足惜腮敌,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望俏扩。 院中可真熱鬧糜工,春花似錦、人聲如沸录淡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嫉戚。三九已至刨裆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間彬檀,已是汗流浹背帆啃。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凤覆,地道東北人链瓦。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像盯桦,于是被迫代替她去往敵國和親慈俯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,526評論 25 707
  • 內容抽屜菜單ListViewWebViewSwitchButton按鈕點贊按鈕進度條TabLayout圖標下拉刷新...
    皇小弟閱讀 46,712評論 22 664
  • 看到阿桑分享的又受到觸動拥峦,沒有想到會有這么相似木馬程序的伙伴贴膘。好像連鎖反應,因為某個問題略号,引起了各種木馬程序刑峡。依賴...
    aseeya閱讀 233評論 0 0
  • 我們都知道混合型的肌膚他就是T區(qū)比較油兩頰比較干。但是也有一些玄柠,常常會遇到一些混合型的肌膚他會很奇怪突梦。他明明t區(qū)會...
    Rbaobao閱讀 845評論 0 0
  • 01 前陣子一篇報道的標題亮了:“殺害金正男的特工身份曝光宫患,疑似是1988年中年女子”——據(jù)說,無數(shù)80后女子看到...
    觀觀之洲閱讀 425評論 -3 4