簡(jiǎn)單造輪子系列 - 自定義支持手勢(shì)旋轉(zhuǎn)的Android Radar Chart(蛛網(wǎng)雷達(dá)圖)

其實(shí)雷達(dá)圖這個(gè)view嘛,繪制起來真的不難,網(wǎng)上也有很多優(yōu)秀的view和教程称簿,主要知識(shí)點(diǎn)就是繪制正N邊形的一個(gè)過程朴爬,也就是對(duì)Path類使用即寒,下面在這里簡(jiǎn)單記錄一下自己的編寫過程和思路,成品效果如下:

首先簡(jiǎn)單的分析一下,繪制這樣一個(gè)雷達(dá)圖大致需要3步:

  1. 繪制所有的正N邊形
  2. 繪制中心點(diǎn)到各頂點(diǎn)的連線
  3. 繪制數(shù)據(jù)區(qū)域N邊形

1母赵、繪制所有的正N邊形

這個(gè)雷達(dá)網(wǎng)由半徑遞減的多個(gè)正N邊形組成逸爵,至于具體繪制幾個(gè),應(yīng)該設(shè)置一個(gè)參數(shù)mLayer以供隨時(shí)調(diào)整凹嘲,這里暫定默認(rèn)值為5师倔。

  • 第一步 找到原點(diǎn)坐標(biāo),這個(gè)好辦周蹭,直接找view的中心點(diǎn)即可
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    mPointCenter = new PointF(w / 2, h / 2);
}
  • 第二步 求出最外層N邊形外接圓半徑趋艘,也就是原點(diǎn)至最外層正N邊形頂點(diǎn)的連線距離,這個(gè)也好辦凶朗,因?yàn)関iew的寬高設(shè)置的并不一定相等瓷胧,所以取view的寬高中小的一個(gè)。但并不能直接將此值作為半徑棚愤,還需要為頂點(diǎn)描述文字預(yù)留空間搓萧,同時(shí)我們也希望頂點(diǎn)描述文字和頂點(diǎn)之間有一定的間距,所以最終半徑的值是在此基礎(chǔ)上再減去頂點(diǎn)描述文字的寬度和間距宛畦。
private void calcRadius() {
        if (mVertexText == null || mVertexText.size() == 0) {
            mRadius = Math.min(mPointCenter.x, mPointCenter.y)
                    - mVertexTextOffset;
        } else {
            String maxText = Collections.max(mVertexText,
                    new Comparator<String>() {
                        @Override
                        public int compare(String lhs, String rhs) {
                            return lhs.length() - rhs.length();
                        }
                    });
            float maxTextWidth = mVertexTextPaint.measureText(maxText);
            if (mVertexTextOffset == 0) {
                Paint.FontMetrics fontMetrics = mVertexTextPaint
                        .getFontMetrics();
                float textHeight = fontMetrics.descent - fontMetrics.ascent;
                mVertexTextOffset = (int) Math.sqrt(Math.pow(maxTextWidth, 2)
                        + Math.pow(textHeight, 2)) / 2;
                if (mVertexTextOffset < dp2px(15)) {
                    mVertexTextOffset = dp2px(15);
                }
            }
            mRadius = Math.min(mPointCenter.x, mPointCenter.y)
                    - (maxTextWidth + mVertexTextOffset);
        }
    }
  • 第三步 繪制所有正N邊形瘸洛,就需要得出正N邊形所有頂點(diǎn)的坐標(biāo),因?yàn)槲覀円呀?jīng)有了N邊形外接圓半徑的值次和,根據(jù)每個(gè)頂點(diǎn)相對(duì)于原點(diǎn)的圓心角度數(shù)反肋,就可以通過三角函數(shù)求出頂點(diǎn)x、y的值踏施,所需公式如下:
x = sin(a) × r y = cos(a) × r a為角石蔗、r為半徑

這里有個(gè)小問題需要注意下,在java中Math類的三角函數(shù)接收的參數(shù)并不角度读规,而是弧度抓督,所以需要用2 * Math.PI表示360°

        mAngle = 2 * Math.PI / mVertexCount;
        for (int i = mLayer; i >= 1; i--) {
              float radius = mRadius / mLayer * i;
              Path p = new Path();
              for (int j = 1; j <= mVertexCount; j++) {
                   float x = (float) (mPointCenter.x + Math.sin(mAngle * j) * radius);
                   float y = (float) (mPointCenter.y + Math.cos(mAngle * j) * radius);
                   if (j == 1) {
                       p.moveTo(x, y);
                   } else {
                       p.lineTo(x, y);
                   }
              }
                   p.close();
                   canvas.drawPath(p, mLayerPaint);
        }

繪制的時(shí)候,我們可以給加點(diǎn)特技什么的束亏,比如每層多邊形的畫筆設(shè)置不同的顏色铃在,效果如下:

或者不繪制多邊形,將雷達(dá)網(wǎng)直接繪制成圓形碍遍,當(dāng)然定铜,繪制圓形就簡(jiǎn)單多了,不需要算頂點(diǎn)的坐標(biāo)怕敬,一句話就搞定

canvas.drawCircle(mPointCenter.x, mPointCenter.y, radius, mLayerPaint);

效果如下:


2揣炕、繪制中心點(diǎn)到各頂點(diǎn)的連線

有了上面的基礎(chǔ),繪制這個(gè)連線就簡(jiǎn)單多了东跪,這里依然使用Path來做連線

        for (int i = 1; i <= mVertexCount; i++) {
             Path p = new Path();
             p.moveTo(mPointCenter.x, mPointCenter.y);
             float x = (float) (mPointCenter.x + Math.sin(mAngle * i) * mRadius);
             float y = (float) (mPointCenter.y + Math.cos(mAngle * i) * mRadius);
             p.lineTo(x, y);
             canvas.drawPath(p, mRadarLinePaint);
        }

同時(shí)還可以把頂點(diǎn)描述文字加上去

for (int i = 1; i <= mVertexCount; i++) {
     float x = (float) (mPointCenter.x + Math.sin(mAngle * i) * (mRadius + mVertexTextOffset));
     float y = (float) (mPointCenter.y + Math.cos(mAngle * i) * (mRadius + mVertexTextOffset));
     String text = mVertexText.get(i - 1);
     float textWidth = mVertexTextPaint.measureText(text);
     Paint.FontMetrics fontMetrics = mVertexTextPaint.getFontMetrics();
     float textHeight = fontMetrics.descent - fontMetrics.ascent;
     canvas.drawText(text, x - textWidth / 2, y + textHeight / 4, mVertexTextPaint);
}

效果如下:

3畸陡、繪制數(shù)據(jù)區(qū)域N邊形

數(shù)據(jù)區(qū)域繪制也是使用Path類鹰溜,方法和繪制雷達(dá)網(wǎng)的N邊形一樣,只是每次半徑的數(shù)值是根據(jù)數(shù)據(jù)的值不斷變化的為了能方便的添加多組數(shù)據(jù)先來定義雷達(dá)圖的數(shù)據(jù)類

public class RadarData {
    private String mLabel;
    private List<Float> mValue;
    private int mColor;
    private List<String> mValueText;
    private int mVauleTextColor;
    private int mValueTextSize;
    private boolean mValueTextEnable;
}

和添加數(shù)據(jù)的方法

public void addData(RadarData data) {
    mRadarData.add(data);
    initData(data);
    animeValue(2000);
}

然后是數(shù)據(jù)區(qū)域內(nèi)容的繪制丁恭,根據(jù)數(shù)據(jù)值占最大值的比例求出半徑

List<Float> values = radarData.getValue();
Path p = new Path();
for (int j = 1; j <= values.size(); j++) {
     float value = values.get(j - 1);
     double percent = value / mMaxValue;
     float x = (float) (mPointCenter.x + Math.sin(mAngle * j + mRotateAngle) * mRadius * percent);
     float y = (float) (mPointCenter.y + Math.cos(mAngle * j + mRotateAngle) * mRadius * percent);
     if (j == 1) {
         p.moveTo(x, y);
     } else {
         p.lineTo(x, y);
     }
}
p.close();
mValuePaint.setAlpha(255);
mValuePaint.setStyle(Paint.Style.STROKE);
canvas.drawPath(p, mValuePaint);
mValuePaint.setStyle(Paint.Style.FILL);
mValuePaint.setAlpha(150);
canvas.drawPath(p, mValuePaint);

效果圖就不貼了曹动,和本文第一張動(dòng)圖一樣,至此整個(gè)雷達(dá)圖就繪制出來了


好了牲览,接下來我們給雷達(dá)圖添加手勢(shì)旋轉(zhuǎn)的功能墓陈,轉(zhuǎn)起來

旋轉(zhuǎn)也不難,不過有個(gè)前提第献,旋轉(zhuǎn)的時(shí)候頂點(diǎn)描述文字雖然也跟著旋轉(zhuǎn)贡必,但其排列方向不能變,任何時(shí)候都要保證是水平排列的庸毫,如果只是簡(jiǎn)單的使用view的setRotation方法來進(jìn)行旋轉(zhuǎn)操作仔拟,就無(wú)法保證文字永遠(yuǎn)是水平排列的,所以我們需要對(duì)各頂點(diǎn)的坐標(biāo)進(jìn)行操作飒赃,使其跟隨手指觸摸移動(dòng)距離整體移動(dòng)理逊,然后不斷的對(duì)整個(gè)視圖進(jìn)行重繪以實(shí)現(xiàn)旋轉(zhuǎn)效果

首先重寫onTouchEvent方法并使用GestureDetector管理觸摸手勢(shì)

    public RadarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mDetector = new GestureDetectorCompat(mContext, new GestureListener());
        mDetector.setIsLongpressEnabled(false);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!mRotationEnable) return super.onTouchEvent(event);
        return mDetector.onTouchEvent(event);
    }

既然要處理手指觸摸移動(dòng),那我們重寫GestureListener的onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)方法

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            double rotate = mRotateAngle;
            double dis = RotateUtil.getRotateAngle(new PointF(e2.getX() - distanceX, e2.getY() - distanceY)
                    , new PointF(e2.getX(), e2.getY()), mPointCenter);
            rotate += dis;
            handleRotate(rotate);
            return super.onScroll(e1, e2, distanceX, distanceY);
        }

這里思路是這樣的盒揉,我們?cè)趏nScroll里計(jì)算本次手指移動(dòng)前后總共移動(dòng)了多少度的角
請(qǐng)看下圖,假設(shè)移動(dòng)前手指在A點(diǎn)兑徘,移動(dòng)后在B點(diǎn)刚盈,目的是根據(jù)移動(dòng)的距離計(jì)算出角a的度數(shù)
計(jì)算出角a的度數(shù)后,就可以重繪view挂脑,還記得我們?cè)谥袄L制正N邊形的時(shí)候各頂點(diǎn)的坐標(biāo)都是使用三角函數(shù)計(jì)算出來的么藕漱,我們只需要在計(jì)算各頂點(diǎn)的時(shí)候,將三角函數(shù)當(dāng)前的角度加上這個(gè)角a崭闲,這樣整個(gè)雷達(dá)圖就旋轉(zhuǎn)了a度肋联,只要手指不斷的移動(dòng),view就會(huì)不斷的旋轉(zhuǎn)刁俭,比如我們挑之前繪制時(shí)第二步繪制中心點(diǎn)到各頂點(diǎn)的連線來改造下

        for (int i = 1; i <= mMaxVertex; i++) {
            Path p = new Path();
            p.moveTo(mPointCenter.x, mPointCenter.y);
            float x = (float) (mPointCenter.x + Math.sin(mAngle * i + mRotateAngle) * mRadius);
            float y = (float) (mPointCenter.y + Math.cos(mAngle * i + mRotateAngle) * mRadius);
            p.lineTo(x, y);
            canvas.drawPath(p, mRadarLinePaint);
        }

其他只要需要計(jì)算頂點(diǎn)的坐標(biāo)的地方都和這個(gè)同樣道理


那么我們?cè)趺从?jì)算出這么一個(gè)移動(dòng)的角度呢橄仍,我這里寫了一個(gè)RotateUtil類專門來處理

public class RotateUtil {
    public static final double CIRCLE_ANGLE = 2 * Math.PI;

    protected static double getRotateAngle(PointF p1, PointF p2, PointF mPointCenter) {
        int q1 = getQuadrant(p1, mPointCenter);
        int q2 = getQuadrant(p2, mPointCenter);
        double angle1 = getAngle(p1, mPointCenter);
        double angle2 = getAngle(p2, mPointCenter);
        if (q1 == q2) {
            return angle1 - angle2;
        } else {
            return 0;
        }
    }

    //得到一個(gè)坐標(biāo)點(diǎn)相對(duì)于原點(diǎn)的圓心角度數(shù)
    public static double getAngle(PointF p, PointF mPointCenter) {
        float x = p.x - mPointCenter.x;
        float y = mPointCenter.y - p.y;
        double angle = Math.atan(y / x);
        return getNormalizedAngle(angle);
    }

    //根據(jù)一個(gè)坐標(biāo)點(diǎn)判斷其所在象限
    public static int getQuadrant(PointF p, PointF mPointCenter) {
        float x = p.x;
        float y = p.y;
        if (x > mPointCenter.x) {
            if (y > mPointCenter.y) {
                return 4;
            } else if (y < mPointCenter.y) {
                return 1;
            }
        } else if (x < mPointCenter.x) {
            if (y > mPointCenter.y) {
                return 3;
            } else if (y < mPointCenter.y) {
                return 2;
            }
        }
        return -1;
    }

    public static double getNormalizedAngle(double angle) {
        while (angle < 0)
            angle += CIRCLE_ANGLE;
        return angle % CIRCLE_ANGLE;
    }
}

其實(shí)邏輯也很簡(jiǎn)單,只需要分別得到A點(diǎn)和B點(diǎn)相對(duì)于原點(diǎn)的圓心角度數(shù)然后相減即可牍戚,那么如果根據(jù)一個(gè)坐標(biāo)點(diǎn)得到角呢侮繁,這里就需要用到反三角函數(shù)了

a = arctan(tan(a)) = arctan(y/x)

這里也有一點(diǎn)需要注意,通過反正切計(jì)算出來角度(其實(shí)是弧度)后如孝,還需要判斷其所在的象限宪哩,我們知道象限角的函數(shù)值是有負(fù)值的,所以如果兩個(gè)角如果不在同一象限第晰,就不能讓其相減

可以看到已經(jīng)可以跟隨手指移動(dòng)進(jìn)行旋轉(zhuǎn)了锁孟,但是仔細(xì)觀察會(huì)發(fā)現(xiàn)一個(gè)問題彬祖,就是旋轉(zhuǎn)的太僵硬了,沒有慣性品抽,這個(gè)好辦储笑,我們可以根據(jù)滑動(dòng)的加速度制造這么一個(gè)fling效果,讓手指滑動(dòng)停止后繼續(xù)旋轉(zhuǎn)一段距離

如何辦到呢桑包,這就需要Scroller出場(chǎng)了南蓬,使用Scroller的fling方法,讓它根據(jù)速度為我們計(jì)算這段距離和時(shí)間哑了,至于速度怎么獲得赘方?,重寫GestureListener中onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)即可

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if (Math.abs(velocityX) > Math.abs(velocityY)) {
                mFlingPoint = e2.getX();
                mScroller.fling((int) e2.getX(), 0, (int) velocityX, 0, (int) (-mPerimeter + e2.getX()), (int) (mPerimeter + e2.getX()), 0, 0);
            } else if (Math.abs(velocityY) > Math.abs(velocityX)) {
                mFlingPoint = e2.getY();
                mScroller.fling(0, (int) e2.getY(), 0, (int) velocityY, 0, 0, (int) (-mPerimeter + e2.getY()), (int) (mPerimeter + e2.getY()));
            }
            invalidate();
            return super.onFling(e1, e2, velocityX, velocityY);
        }

fling的min和max的值使用最外層N邊形外接圓的周長(zhǎng)來做限制弱左,當(dāng)然這可以按照自己的想法隨意制訂窄陡,想轉(zhuǎn)的距離再長(zhǎng)點(diǎn)加大這個(gè)值的范圍就行了

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            int x = mScroller.getCurrX();
            int y = mScroller.getCurrY();
            int max = Math.max(Math.abs(x), Math.abs(y));
            double rotateDis = RotateUtil.CIRCLE_ANGLE * (Math.abs(max - mFlingPoint) / mPerimeter);
            double rotate = mRotateAngle;
            if (mRotateOrientation > 0) {
                rotate += rotateDis;
            } else if (mRotateOrientation < 0) {
                rotate -= rotateDis;
            }
            handleRotate(rotate);
            mFlingPoint = max;
            invalidate();
        }
    }

computeScroll里,按照滑動(dòng)距離相對(duì)于外接圓周長(zhǎng)的占比求出旋轉(zhuǎn)的角度拆火,重繪view即可

可以看到已經(jīng)能比較順滑的旋轉(zhuǎn)了

最后跳夭,我們?cè)俳o數(shù)據(jù)區(qū)加一個(gè)動(dòng)畫效果,直接用屬性動(dòng)畫就好们镜,比較簡(jiǎn)單沒什么可說的币叹,直接上代碼吧

    public void animeValue(int duration){
        for (int i = 0; i < mRadarData.size(); i++) {
            RadarData data = mRadarData.get(i);
            ValueAnimator anime = ValueAnimator.ofFloat(0, 1f);
            final List<Float> values = data.getValue();
            final List<Float> values2 = new ArrayList<>(values);
            anime.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float percent = Float.parseFloat(animation.getAnimatedValue().toString());
                    for (int i = 0; i < values.size(); i++) {
                        values.set(i, values2.get(i) * percent);
                    }
                    invalidate();
                }
            });
            anime.setDuration(duration).start();
        }
    }

就先寫這么一個(gè)動(dòng)畫吧,以后想到別的了再慢慢加進(jìn)去

github:https://github.com/qstumn/RadarView

感謝:http://blog.csdn.net/crazy__chen/article/details/50163693

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末模狭,一起剝皮案震驚了整個(gè)濱河市颈抚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嚼鹉,老刑警劉巖贩汉,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異锚赤,居然都是意外死亡匹舞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門线脚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赐稽,“玉大人,你說我怎么就攤上這事酒贬∮趾” “怎么了?”我有些...
    開封第一講書人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵锭吨,是天一觀的道長(zhǎng)蠢莺。 經(jīng)常有香客問我,道長(zhǎng)零如,這世上最難降的妖魔是什么躏将? 我笑而不...
    開封第一講書人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任锄弱,我火速辦了婚禮,結(jié)果婚禮上祸憋,老公的妹妹穿的比我還像新娘会宪。我一直安慰自己,他們只是感情好蚯窥,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開白布掸鹅。 她就那樣靜靜地躺著,像睡著了一般拦赠。 火紅的嫁衣襯著肌膚如雪巍沙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,184評(píng)論 1 308
  • 那天荷鼠,我揣著相機(jī)與錄音句携,去河邊找鬼。 笑死允乐,一個(gè)胖子當(dāng)著我的面吹牛矮嫉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播牍疏,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼蠢笋,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了鳞陨?” 一聲冷哼從身側(cè)響起挺尿,我...
    開封第一講書人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炊邦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體熟史,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡馁害,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蹂匹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碘菜。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖限寞,靈堂內(nèi)的尸體忽然破棺而出忍啸,到底是詐尸還是另有隱情,我是刑警寧澤履植,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布计雌,位于F島的核電站,受9級(jí)特大地震影響玫霎,放射性物質(zhì)發(fā)生泄漏凿滤。R本人自食惡果不足惜妈橄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望翁脆。 院中可真熱鬧眷蚓,春花似錦、人聲如沸反番。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)罢缸。三九已至篙贸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間祖能,已是汗流浹背歉秫。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留养铸,地道東北人雁芙。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像钞螟,于是被迫代替她去往敵國(guó)和親兔甘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,275評(píng)論 25 707
  • 當(dāng)你對(duì)各種軍用雷達(dá)頭大的時(shí)候鳞滨,推薦你讀讀這一篇洞焙。 艦載雷達(dá) |型號(hào)|應(yīng)用||:-:|:-:|:-:|:-:|:-:...
    好心態(tài)閱讀 6,902評(píng)論 0 7
  • 歲數(shù)大了,注意力早已不集中了拯啦,只能用筆記本記下澡匪,可現(xiàn)在搞得連筆記本都不知道丟哪了,這才是尷尬的地方褒链。
    東甌國(guó)老何閱讀 274評(píng)論 0 0
  • 當(dāng)太晚將要升起 我就踩在海岸上 我追逐著那一抹心頭的溫暖 當(dāng)背影投射在沙灘上 正好遇到你迎面而來的笑容 剎那暈開了...
    田萍閱讀 292評(píng)論 2 8
  • 看經(jīng)濟(jì)學(xué)書要讀出來 小聲讀唁情,快讀 2.自己說話好多時(shí)間就是沒邏輯的主要問題就是小邏輯結(jié)構(gòu)不總結(jié),就是眉毛胡子一把抓...
    智囊團(tuán)閱讀 148評(píng)論 0 0