仿百度外賣的酷炫水波紋效果及解析

前言:在網(wǎng)上經(jīng)常會(huì)看到別人寫(xiě)的一些開(kāi)源項(xiàng)目,然后會(huì)驚嘆于他們的寫(xiě)的效果,當(dāng)然那些大神也會(huì)把代碼放出來(lái),然后供大家看,但是因?yàn)樗麄兪亲约簩?xiě)的,所以有些地方就是單純的貼了代碼,讓大家自己去看。介于我前面動(dòng)畫(huà)方面比較薄弱,所以有些地方就要一邊跟著敲代碼,一邊去網(wǎng)上查相關(guān)知識(shí)。所以就借這次機(jī)會(huì)。我來(lái)寫(xiě)下我最近學(xué)的動(dòng)畫(huà)效果及相關(guān)的知識(shí)。

---------------------------------------我是前言分割君-------------------------------------------

感謝CSDN的Zcoder2013,最后附上文字鏈接。

--------------------------------正文君打工的溫州皮革廠倒閉了-------------------------------

仿百度外賣個(gè)人中心效果

仿百度外賣的個(gè)人中心

強(qiáng)烈建議看下自定義View的整個(gè)教程
從零起步,從入門到懵逼的自定義 View 教程
從零起步,從入門到懵逼的自定義 View 教程
從零起步,從入門到懵逼的自定義 View 教程
(重要的事情說(shuō)三遍)(重要的事情說(shuō)三遍)(重要的事情說(shuō)三遍)

-----------------------------------分析君帶著小姨子逃跑了-------------------------

我們先來(lái)看下這個(gè)自定義的View的代碼是如何實(shí)現(xiàn)的。

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;



public class WaveView extends View{

    private Path mAbovePath,mBelowWavePath;
    private Paint mAboveWavePaint,mBelowWavePaint;
    private DrawFilter mDrawFilter;
    private float φ;
    private OnWaveAnimationListener mWaveAnimationListener;

    public WaveView(Context context, AttributeSet attrs) {
        super(context, attrs);

        //初始化路徑
        mAbovePath = new Path();
        mBelowWavePath = new Path();

        //初始化畫(huà)筆
        mAboveWavePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mAboveWavePaint.setAntiAlias(true);
        mAboveWavePaint.setStyle(Paint.Style.FILL);
        mAboveWavePaint.setColor(Color.WHITE);

        mBelowWavePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBelowWavePaint.setAntiAlias(true);
        mBelowWavePaint.setStyle(Paint.Style.FILL);
        mBelowWavePaint.setColor(Color.WHITE);
        mBelowWavePaint.setAlpha(80);

        //畫(huà)布抗鋸齒
        mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.setDrawFilter(mDrawFilter);

        mAbovePath.reset();
        mBelowWavePath.reset();

        φ-=0.1f;
        float y,y2;
        double ω = 2*Math.PI / getWidth();

        mAbovePath.moveTo(getLeft(),getBottom());
        mBelowWavePath.moveTo(getLeft(),getBottom());

        for (float x = 0; x <= getWidth(); x += 20) {
            /**
             *  y=Asin(ωx+φ)+k
             *  A—振幅越大,波形在y軸上最大與最小值的差值越大
             *  ω—角速度, 控制正弦周期(單位角度內(nèi)震動(dòng)的次數(shù))
             *  φ—初相,反映在坐標(biāo)系上則為圖像的左右移動(dòng)。這里通過(guò)不斷改變?chǔ)?達(dá)到波浪移動(dòng)效果
             *  k—偏距,反映在坐標(biāo)系上則為圖像的上移或下移。
             */
            y = (float) (8 * Math.cos(ω * x + φ) +8);
            y2 = (float) (8 * Math.sin(ω * x + φ));
            mAbovePath.lineTo(x, y);
            mBelowWavePath.lineTo(x, y2);
            //回調(diào) 把y坐標(biāo)的值傳出去(在activity里面接收讓小機(jī)器人隨波浪一起搖擺)
            mWaveAnimationListener.OnWaveAnimation(y);
        }

       
        mAbovePath.lineTo(getRight(),getBottom());
        mBelowWavePath.lineTo(getRight(),getBottom());

        canvas.drawPath(mAbovePath,mAboveWavePaint);
        canvas.drawPath(mBelowWavePath,mBelowWavePaint);

        postInvalidateDelayed(20);
    }

    public void setOnWaveAnimationListener(OnWaveAnimationListener l){
        this.mWaveAnimationListener = l;
    }

    public interface OnWaveAnimationListener{
        void OnWaveAnimation(float y);
    }
}

我們一步步來(lái)分析。首先我們要自定義一個(gè)View。

自定義View流程:

步驟 關(guān)鍵字 作用
1 構(gòu)造函數(shù) View初始化
2 onMeasure 測(cè)量View大小
3 onSizeChanged 確定View大小
4 onLayout 確定子View布局(自定義View包含子View時(shí)有用)
5 onDraw 實(shí)際繪制內(nèi)容
6 提供接口 控制View或監(jiān)聽(tīng)View某些狀態(tài)。

我們來(lái)講解下上圖中的這幾個(gè)我們等會(huì)會(huì)使用到的重要方法:

1.構(gòu)造函數(shù)

構(gòu)造函數(shù)是View的入口,可以用于初始化一些的內(nèi)容,和獲取自定義屬性
View的構(gòu)造函數(shù)有四種重載分別如下:

public void WaveView(Context context) {}
public void WaveView(Context context, AttributeSet attrs) {}
public void WaveView(Context context, AttributeSet attrs, int defStyleAttr) {}
public void WaveView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {}

有四個(gè)參數(shù)的構(gòu)造函數(shù)在API21的時(shí)候才添加上,暫不考慮。
有三個(gè)參數(shù)的構(gòu)造函數(shù)中第三個(gè)參數(shù)是默認(rèn)的Style,這里的默認(rèn)的Style是指它在當(dāng)前Application或Activity所用的Theme中的默認(rèn)Style,且只有在明確調(diào)用的時(shí)候才會(huì)生效,以系統(tǒng)中的ImageButton為例說(shuō)明:

    public WaveView(Context context, AttributeSet attrs) {
        //調(diào)用了三個(gè)參數(shù)的構(gòu)造函數(shù),明確指定第三個(gè)參數(shù)
        this(context, attrs, com.android.internal.R.attr.imageButtonStyle);
    }

    public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
        //此處調(diào)了四個(gè)參數(shù)的構(gòu)造函數(shù),無(wú)視即可
        this(context, attrs, defStyleAttr, 0); 
    }

注意:即使你在View中使用了Style這個(gè)屬性也不會(huì)調(diào)用三個(gè)參數(shù)的構(gòu)造函數(shù),所調(diào)用的依舊是兩個(gè)參數(shù)的構(gòu)造函數(shù)。
由于三個(gè)參數(shù)的構(gòu)造函數(shù)第三個(gè)參數(shù)一般不用,暫不考慮,第三個(gè)參數(shù)的具體用法會(huì)在以后用到的時(shí)候詳細(xì)介紹。
排除了兩個(gè)之后,只剩下一個(gè)參數(shù)和兩個(gè)參數(shù)的構(gòu)造函數(shù),他們的詳情如下:

  //一般在直接New一個(gè)View的時(shí)候調(diào)用。
  public void WaveView(Context context) {}

  //一般在layout文件中使用的時(shí)候會(huì)調(diào)用,關(guān)于它的所有屬性(包括自定義屬性)都會(huì)包含在attrs中傳遞進(jìn)來(lái)。
  public void WaveView(Context context, AttributeSet attrs) {}
**以下方法調(diào)用的是一個(gè)參數(shù)的構(gòu)造函數(shù):**
//在Avtivity中 WaveView view = new WaveView(this);

以下方法調(diào)用的是兩個(gè)參數(shù)的構(gòu)造函數(shù):

  //在layout文件中 - 格式為: 包名.View名
  <com.androiddemo.waveview.WaveView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

因?yàn)槲覀冞@個(gè)例子中是在layout中使用這個(gè)自定義View。所以我們當(dāng)前例子里面,只需要留下二個(gè)參數(shù)的public void WaveView(Context context, AttributeSet attrs) {}構(gòu)造函數(shù)即可。

2.繪制內(nèi)容(onDraw)

onDraw是實(shí)際繪制的部分,也就是我們真正關(guān)心的部分,使用的是Canvas繪圖。

@Override 
protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
}

我們是不是在想這個(gè)百度個(gè)人中心效果到底是怎么實(shí)現(xiàn)的,在這里我要貼個(gè)圖:


sin函數(shù)及cos函數(shù)

哈哈。沒(méi)錯(cuò)。那二個(gè)上下浮動(dòng)的曲線。我們可以用同時(shí)畫(huà)二個(gè)線,一個(gè)sin函數(shù),一個(gè)cos函數(shù)。而且處于同一水平線。不就一個(gè)交錯(cuò)的波浪了。

類似這樣的效果

好,第一步的大概思路咱們有了。咱們?cè)偎伎既绾萎?huà)這些線呢。
這里先介紹幾個(gè)基本知識(shí)點(diǎn):

  • 了解Path:
    不清楚這個(gè)Path的一定要一定要一定要看下面這個(gè)Path基礎(chǔ)鏈接
    Path之基本操作

官方介紹:
The Path class encapsulates compound (multiple contour) geometric paths consisting of straight line segments, quadratic curves, and cubic curves. It can be drawn with canvas.drawPath(path, paint), either filled or stroked (based on the paint's Style), or it can be used for clipping or to draw text on a path.
嗯,沒(méi)錯(cuò)依舊是拿來(lái)裝逼的,如果你看不懂的話,不用擔(dān)心,其實(shí)并沒(méi)有什么卵用。

通俗解釋:
Path封裝了由直線和曲線(二次,三次貝塞爾曲線)構(gòu)成的幾何路徑。你能用Canvas中的drawPath來(lái)把這條路徑畫(huà)出來(lái)(同樣支持Paint的不同繪制模式),也可以用于剪裁畫(huà)布和根據(jù)路徑繪制文字。我們有時(shí)會(huì)用Path來(lái)描述一個(gè)圖像的輪廓,所以也會(huì)稱為輪廓線(輪廓線僅是Path的一種使用方法,兩者并不等價(jià))

我就列舉出我們這次的仿百度效果會(huì)使用的幾個(gè)方法:

作用 相關(guān)方法 備注
移動(dòng)起點(diǎn) moveTo 移動(dòng)下一次操作的起點(diǎn)位置
連接直線 lineTo 添加上一個(gè)點(diǎn)到當(dāng)前點(diǎn)之間的直線到Path
重置路徑 reset, rewind 清除Path中的內(nèi)容reset不保留內(nèi)部數(shù)據(jù)結(jié)構(gòu),但會(huì)保留FillType.****rewind會(huì)保留內(nèi)部的數(shù)據(jù)結(jié)構(gòu),但不保留FillType

沒(méi)錯(cuò)。為啥我列舉了這幾個(gè)方法呢。有人要問(wèn),lineTo不是畫(huà)直線的么。其實(shí)這個(gè)sin和cos曲線就是被我們一小段一小段的用線段畫(huà)出來(lái)的。

哈哈,純手工畫(huà)的
      /**
         *  y=Asin(ωx+φ)+k
         *  A—振幅越大,波形在y軸上最大與最小值的差值越大
         *  ω—角速度, 控制正弦周期(單位角度內(nèi)震動(dòng)的次數(shù))
         *  φ—初相,反映在坐標(biāo)系上則為圖像的左右移動(dòng)。這里通過(guò)不斷改變?chǔ)?達(dá)到波浪移動(dòng)效果
         *  k—偏距,反映在坐標(biāo)系上則為圖像的上移或下移。
         */

比如畫(huà)上述這個(gè)sin函數(shù)。我們畫(huà)好后。怎么讓他不停的往左移動(dòng),產(chǎn)生波浪的效果呢。這時(shí)候就會(huì)想到重新繪制,然后再畫(huà)一遍,但是這時(shí)候不能原來(lái)這個(gè)sin函數(shù)。sin里面的φ參數(shù)要變一下,這樣再次重繪的時(shí)候。新畫(huà)出來(lái)的sin線就是一個(gè)被左右方向移動(dòng)后的線了。給你的感覺(jué)不就是像波浪一樣往右邊移動(dòng)了?。。?!

所以我們就知道了:(以sin為例)

  1. 畫(huà)出用lineTo在X軸上畫(huà)出一段段小的線段,拼成一個(gè)sin曲線圖
  2. 畫(huà)完這個(gè)曲線后重新執(zhí)行繪圖,這時(shí)候的改變sin函數(shù)內(nèi)部參數(shù),畫(huà)出來(lái)的曲線已經(jīng)在上一次的曲線的基礎(chǔ)上被左右移動(dòng)過(guò)了。

這下了解了這些。我們?cè)僮屑?xì)的分析下onDraw方法的代碼:

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.setDrawFilter(mDrawFilter);

        mAbovePath.reset();
        mBelowWavePath.reset();

        φ-=0.1f;
        float y,y2;
        double ω = 2*Math.PI / getWidth();

        mAbovePath.moveTo(getLeft(),getBottom());
        mBelowWavePath.moveTo(getLeft(),getBottom());

        for (float x = 0; x <= getWidth(); x += 20) {
            /**
             *  y=Asin(ωx+φ)+k
             *  A—振幅越大,波形在y軸上最大與最小值的差值越大
             *  ω—角速度, 控制正弦周期(單位角度內(nèi)震動(dòng)的次數(shù))
             *  φ—初相,反映在坐標(biāo)系上則為圖像的左右移動(dòng)。這里通過(guò)不斷改變?chǔ)?達(dá)到波浪移動(dòng)效果
             *  k—偏距,反映在坐標(biāo)系上則為圖像的上移或下移。
             */
            y = (float) (8 * Math.cos(ω * x + φ) +8);
            y2 = (float) (8 * Math.sin(ω * x + φ));
            mAbovePath.lineTo(x, y);
            mBelowWavePath.lineTo(x, y2);
            //回調(diào) 把y坐標(biāo)的值傳出去(在activity里面接收讓小機(jī)器人隨波浪一起搖擺)
            mWaveAnimationListener.OnWaveAnimation(y);
        }

       
        mAbovePath.lineTo(getRight(),getBottom());
        mBelowWavePath.lineTo(getRight(),getBottom());

        canvas.drawPath(mAbovePath,mAboveWavePaint);
        canvas.drawPath(mBelowWavePath,mBelowWavePaint);

        postInvalidateDelayed(20);
    }

第一步:我們可以看到它是先通過(guò)for循環(huán)

for (float x = 0; x <= getWidth(); x += 20) {
          
}

把這個(gè)繪畫(huà)的曲線在X軸上分割成為一段段。每一段再用線段畫(huà)出來(lái)就可以了。

又是丑丑的手工畫(huà)圖

而每一段的畫(huà)又是要按照sin或者cos的函數(shù)來(lái)畫(huà)。并且是通過(guò)lineTo方法來(lái)。所以最后合在一起就是:

for (float x = 0; x <= getWidth(); x += 20) {
            /**
             *  y=Asin(ωx+φ)+k
             *  A—振幅越大,波形在y軸上最大與最小值的差值越大
             *  ω—角速度, 控制正弦周期(單位角度內(nèi)震動(dòng)的次數(shù))
             *  φ—初相,反映在坐標(biāo)系上則為圖像的左右移動(dòng)。這里通過(guò)不斷改變?chǔ)?達(dá)到波浪移動(dòng)效果
             *  k—偏距,反映在坐標(biāo)系上則為圖像的上移或下移。
             */
            y = (float) (8 * Math.cos(ω * x + φ) +8);
            y2 = (float) (8 * Math.sin(ω * x + φ));
            mAbovePath.lineTo(x, y);
            mBelowWavePath.lineTo(x, y2);
        }

這時(shí)候如果我們canvas.drawPath方法來(lái)畫(huà)出我們上面的這個(gè)處理過(guò)的path。就可以畫(huà)出來(lái)相應(yīng)的sin或者cos線了。

第二步:重新繪制曲線
在onDraw()方法的結(jié)尾處加上:
postInvalidateDelayed(20);
這個(gè)方法會(huì)再20毫秒后會(huì)重新調(diào)用onDraw()方法。
然后再onDraw()方法的開(kāi)始部分。我們要把path重新置空:
mAbovePath.reset(); mBelowWavePath.reset();
然后改變Asin(ωx+φ)+k的(φ—初相)這個(gè)值:
φ-=0.1f;
從而再一次畫(huà)出來(lái)的曲線就已經(jīng)左右被移動(dòng)過(guò)了。讓你產(chǎn)生波浪的感覺(jué)。


好的,我們已經(jīng)學(xué)完了那二個(gè)波浪的成(zhuang)功(B)實(shí)現(xiàn)了。如何來(lái)實(shí)現(xiàn)那個(gè)頭像跟隨著曲線一起動(dòng)呢。其實(shí)很簡(jiǎn)單。剛才我們能畫(huà)出曲線。是通過(guò)Path 的lineTo方法不斷的傳入相應(yīng)的(x,y)坐標(biāo),從而畫(huà)出一個(gè)個(gè)線段,從而拼成了曲線,那就是我們能拿到每個(gè)線段的Y軸坐標(biāo)上的值。也就是:

y = (float) (8 * Math.cos(ω * x + φ) +8);
y2 = (float) (8 * Math.sin(ω * x + φ));

那我們只要:

  1. 拿到圖片對(duì)象:
    imageView = (ImageView) findViewById(R.id.image);
  2. 把上面的曲線的y或者y1值拿過(guò)來(lái),比如我拿的是y。
  3. 讓imageView與它的父View之間的margin中的bottom屬性值等于這個(gè)y的值就可以了(demo里面是y+2)。這樣就不停的上下的浮動(dòng)了。
lp.setMargins(0,0,0,(int)y+2); 
imageView.setLayoutParams(lp);

附上Activity及l(fā)ayout的代碼:

Activity:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.ImageView;

import yunyuan.androiddemo.R;

/**
 * Created by willy on 16/12/12.
 */

public class WaveActivity extends AppCompatActivity {

    private ImageView imageView;
    private WaveView waveView3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_waveview);
        imageView = (ImageView) findViewById(R.id.image);
        waveView3 = (WaveView) findViewById(R.id.wave_view);

        final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(-2,-2);
        lp.gravity = Gravity.BOTTOM|Gravity.CENTER;
        waveView3.setOnWaveAnimationListener(new WaveView.OnWaveAnimationListener() {
            @Override
            public void OnWaveAnimation(float y) {
                lp.setMargins(0,0,0,(int)y+2);
                imageView.setLayoutParams(lp);
            }
        });
    }
}

layout:

<?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:background="#ffffff"
    android:orientation="vertical">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="@android:color/holo_red_dark"
        >

        <yunyuan.androiddemo.waveview.WaveView
            android:id="@+id/wave_view"
            android:layout_width="match_parent"
            android:layout_height="15dp"
            android:layout_gravity="bottom" />

        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center"
            android:background="@mipmap/ic_launcher" />

    </FrameLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="其他內(nèi)容"
            android:textSize="24sp" />

    </LinearLayout>

</LinearLayout>

最后咱們做出來(lái)的效果圖就是這樣滴:


最后再次感謝大神感謝CSDN的Zcoder2013
文章鏈接:http://blog.csdn.net/u011507982/article/details/53414422

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評(píng)論 6 546
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,814評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,980評(píng)論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 64,064評(píng)論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,779評(píng)論 6 414
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 56,109評(píng)論 1 330
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,287評(píng)論 0 291
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,799評(píng)論 1 338
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,515評(píng)論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,750評(píng)論 1 375
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,933評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,327評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,667評(píng)論 1 296
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,492評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,703評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,809評(píng)論 25 708
  • 本篇文章已授權(quán)微信公眾號(hào) guolin_blog (郭霖)獨(dú)家發(fā)布轉(zhuǎn)載請(qǐng)標(biāo)明出處: http://www.jian...
    張旭童閱讀 12,024評(píng)論 22 98
  • 前言 使用百度貼吧客戶端的時(shí)候發(fā)發(fā)現(xiàn)加載的小動(dòng)畫(huà)挺有意思的,于是自己動(dòng)手寫(xiě)寫(xiě)看。想學(xué)習(xí)自定義View以及自定義動(dòng)畫(huà)...
    Jics閱讀 4,689評(píng)論 31 108
  • 方式1、直接修改: git remote set-url origin xxxxx.git 方式2、先刪后加 : ...
    CaiBird閱讀 3,496評(píng)論 0 0
  • 這是一個(gè)真實(shí)的故事,我的高中同學(xué),平時(shí)兢兢業(yè)業(yè),不聰明卻十分努力,由于各種原因總被欺負(fù),老師看他努力,于是讓他做了...
    人海中孤獨(dú)旅行閱讀 341評(píng)論 0 1