【高仿微信系列】03、微信录制小视频

本文为个人原创,欢迎转载,但请务必在明显位置注明出处!

GitHub地址:https://github.com/motianhuo/wechat

微信从6.0版本开始推出小视频功能,随着4G网络的出现,视频将会是一个趋势,他能表达出文字所不能表现的东西,增加了微信的黏性。还记得微信小视频这个功能一推出,如同病毒一样席卷朋友圈。

微信小视频

作为爱美的我们,怎么能把我们的窘态暴露给朋友圈的小伙伴呢,必须正能量!美好的!必须美化! So,录制小视频后,加各种滤镜,炫酷MV主题,妈妈再也不担心我的猪窝了…

“小视频”对于微信如此之重要。那么,如何实现呢? 
先看下咱们的实现效果:

高仿微信 小视频

PS:gif 图片比较大,如果等不及的童鞋,可以点击这里查看视频

OK,先看下,消息列表页面的 下滑显示眼睛动画效果的实现方式: 
自定义ListView:PullDownListView.java 
PullDownListView来自guojunyi的分享, GitHub项目地址:点击这里

package com.example.wechat01.widght;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.RelativeLayout;

import com.example.wechat01.R;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;

public class PullDownListView extends RelativeLayout implements
        OnScrollListener {
    static int MAX_PULL_TOP_HEIGHT;
    static int MAX_PULL_BOTTOM_HEIGHT;

    static int REFRESHING_TOP_HEIGHT;
    static int REFRESHING_BOTTOM_HEIGHT;

    private boolean isTop;
    private boolean isBottom;
    private boolean isRefreshing;
    private boolean isAnimation;

    RelativeLayout layoutHeader;
    RelativeLayout layoutFooter;

    private int mCurrentY = 0;
    boolean pullTag = false;
    OnScrollListener mOnScrollListener;
    OnPullHeightChangeListener mOnPullHeightChangeListener;

    public void setOnPullHeightChangeListener(
            OnPullHeightChangeListener listener) {
        this.mOnPullHeightChangeListener = listener;
    }

    public void setOnScrollListener(OnScrollListener listener) {
        mOnScrollListener = listener;
    }

    public PullDownListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public boolean isRefreshing() {
        return this.isRefreshing;
    }

    private ListView mListView = new ListView(getContext()) {

        int lastY = 0;

        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            if (isAnimation || isRefreshing) {
                return super.onTouchEvent(ev);
            }
            RelativeLayout parent = (RelativeLayout) mListView.getParent();

            int currentY = (int) ev.getRawY();
            switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastY = (int) ev.getRawY();
                break;
            case MotionEvent.ACTION_MOVE: {
                boolean isToBottom = currentY - lastY >= 0 ? true : false;

                int step = Math.abs(currentY - lastY);
                lastY = currentY;

                if (isTop && mListView.getTop() >= 0) {

                    if (isToBottom && mListView.getTop() <= MAX_PULL_TOP_HEIGHT) {
                        MotionEvent event = MotionEvent.obtain(ev);
                        ev.setAction(MotionEvent.ACTION_UP);
                        super.onTouchEvent(ev);
                        pullTag = true;

                        if (mListView.getTop() > layoutHeader.getHeight()) {
                            step = step / 2;
                        }
                        if ((mListView.getTop() + step) > MAX_PULL_TOP_HEIGHT) {
                            mCurrentY = MAX_PULL_TOP_HEIGHT;
                            scrollTopTo(mCurrentY);
                        } else {
                            mCurrentY += step;
                            scrollTopTo(mCurrentY);
                        }
                    } else if (!isToBottom && mListView.getTop() > 0) {
                        MotionEvent event = MotionEvent.obtain(ev);
                        ev.setAction(MotionEvent.ACTION_UP);
                        super.onTouchEvent(ev);
                        if ((mListView.getTop() - step) < 0) {
                            mCurrentY = 0;
                            scrollTopTo(mCurrentY);
                        } else {
                            mCurrentY -= step;
                            scrollTopTo(mCurrentY);
                        }
                    } else if (!isToBottom && mListView.getTop() == 0) {
                        if (!pullTag) {
                            return super.onTouchEvent(ev);
                        }

                    }

                    return true;
                } else if (isBottom
                        && mListView.getBottom() <= parent.getHeight()) {
                    if (!isToBottom
                            && (parent.getHeight() - mListView.getBottom()) <= MAX_PULL_BOTTOM_HEIGHT) {
                        MotionEvent event = MotionEvent.obtain(ev);
                        ev.setAction(MotionEvent.ACTION_UP);
                        super.onTouchEvent(ev);
                        pullTag = true;
                        if (parent.getHeight() - mListView.getBottom() > layoutFooter
                                .getHeight()) {
                            step = step / 2;
                        }

                        if ((mListView.getBottom() - step) < (parent
                                .getHeight() - MAX_PULL_BOTTOM_HEIGHT)) {
                            mCurrentY = -MAX_PULL_BOTTOM_HEIGHT;
                            scrollBottomTo(mCurrentY);
                        } else {
                            mCurrentY -= step;
                            scrollBottomTo(mCurrentY);
                        }
                    } else if (isToBottom
                            && (mListView.getBottom() < parent.getHeight())) {
                        if ((mListView.getBottom() + step) > parent.getHeight()) {
                            mCurrentY = 0;
                            scrollBottomTo(mCurrentY);
                        } else {
                            mCurrentY += step;
                            scrollBottomTo(mCurrentY);
                        }
                    } else if (isToBottom
                            && mListView.getBottom() == parent.getHeight()) {
                        if (!pullTag) {
                            return super.onTouchEvent(ev);
                        }
                    }
                    return true;
                }
                break;
            }
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                pullTag = false;

                if (mListView.getTop() > 0) {
                    if (mListView.getTop() > REFRESHING_TOP_HEIGHT) {
                        animateTopTo(layoutHeader.getMeasuredHeight());
                        isRefreshing = true;
                        if (null != mOnPullHeightChangeListener) {
                            mOnPullHeightChangeListener.onRefreshing(true);
                        }
                    } else {
                        animateTopTo(0);
                    }

                } else if (mListView.getBottom() < parent.getHeight()) {
                    if ((parent.getHeight() - mListView.getBottom()) > REFRESHING_BOTTOM_HEIGHT) {
                        animateBottomTo(-layoutFooter.getMeasuredHeight());
                        isRefreshing = true;
                        if (null != mOnPullHeightChangeListener) {
                            mOnPullHeightChangeListener.onRefreshing(false);
                        }
                    } else {
                        animateBottomTo(0);
                    }
                }

            }

            return super.onTouchEvent(ev);
        }

    };

    public void scrollBottomTo(int y) {
        mListView.layout(mListView.getLeft(), y, mListView.getRight(),
                this.getMeasuredHeight() + y);
        if (null != mOnPullHeightChangeListener) {
            mOnPullHeightChangeListener.onBottomHeightChange(
                    layoutHeader.getHeight(), -y);
        }
    }

    public void animateBottomTo(final int y) {
        ValueAnimator animator = ValueAnimator.ofInt(mListView.getBottom()
                - this.getMeasuredHeight(), y);
        animator.setDuration(300);
        animator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // TODO Auto-generated method stub
                int frameValue = (Integer) animation.getAnimatedValue();
                mCurrentY = frameValue;
                scrollBottomTo(frameValue);
                if (frameValue == y) {
                    isAnimation = false;
                }
            }
        });
        isAnimation = true;
        animator.start();
    }

    public void scrollTopTo(int y) {
        mListView.layout(mListView.getLeft(), y, mListView.getRight(),
                this.getMeasuredHeight() + y);
        if (null != mOnPullHeightChangeListener) {
            mOnPullHeightChangeListener.onTopHeightChange(
                    layoutHeader.getHeight(), y);
        }
    }

    public void animateTopTo(final int y) {
        ValueAnimator animator = ValueAnimator.ofInt(mListView.getTop(), y);
        animator.setDuration(300);
        animator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // TODO Auto-generated method stub
                int frameValue = (Integer) animation.getAnimatedValue();
                mCurrentY = frameValue;
                scrollTopTo(frameValue);
                if (frameValue == y) {
                    isAnimation = false;
                }
            }
        });
        isAnimation = true;
        animator.start();
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        REFRESHING_TOP_HEIGHT = layoutHeader.getMeasuredHeight();
        REFRESHING_BOTTOM_HEIGHT = layoutFooter.getMeasuredHeight();

        MAX_PULL_TOP_HEIGHT = this.getMeasuredHeight();
        MAX_PULL_BOTTOM_HEIGHT = this.getMeasuredHeight();
    }

    @Override
    public void onFinishInflate() {

        mListView.setBackgroundColor(0xffffffff);
        mListView.setCacheColorHint(Color.TRANSPARENT);
        mListView.setVerticalScrollBarEnabled(false);
        mListView.setLayoutParams(new RelativeLayout.LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        mListView.setOnScrollListener(this);
        mListView.setDividerHeight(0);
        this.addView(mListView);

        layoutHeader = (RelativeLayout) this.findViewById(R.id.layoutHeader);
        layoutFooter = (RelativeLayout) this.findViewById(R.id.layoutFooter); 
        super.onFinishInflate();
    }

    public ListView getListView() {
        return this.mListView;
    } 
    public void pullUp() {
        isRefreshing = false;
        if (mListView.getTop() > 0) {
            animateTopTo(0);
        } else if (mListView.getBottom() < this.getHeight()) {
            animateBottomTo(0);
        } 
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        // TODO Auto-generated method stub
        if (null != mOnScrollListener) {
            mOnScrollListener.onScroll(view, firstVisibleItem,
                    visibleItemCount, totalItemCount);
        }
        if (mListView.getCount() > 0) {
            if ((firstVisibleItem + visibleItemCount) == totalItemCount) {
                View lastItem = (View) mListView
                        .getChildAt(visibleItemCount - 1);
                if (null != lastItem) {

                    if (lastItem.getBottom() == mListView.getHeight()) {
                        Log.e("my", lastItem.getBottom() + "");
                        isBottom = true;
                    } else {
                        isBottom = false;
                    }
                }
            } else {
                isBottom = false;
            }
        } else {
            isBottom = false;
        }
        if (mListView.getCount() > 0) {
            if (firstVisibleItem == 0) {
                View firstItem = mListView.getChildAt(0);
                if (null != firstItem) {
                    if (firstItem.getTop() == 0) {
                        isTop = true;
                    } else {
                        isTop = false;
                    }
                }
            } else {
                isTop = false;
            }
        } else {
            isTop = true;
        }
    }
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // TODO Auto-generated method stub
        if (null != mOnScrollListener) {
            mOnScrollListener.onScrollStateChanged(view, scrollState);
        }
    }
    // listener call back
    public interface OnPullHeightChangeListener {
        public void onTopHeightChange(int headerHeight, int pullHeight);
        public void onBottomHeightChange(int footerHeight, int pullHeight);
        public void onRefreshing(boolean isTop);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345

再看,小眼睛的实现方式:EyeView.java

package com.example.wechat01.widght;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.widget.ImageView;

import com.example.wechat01.R;

public class EyeView extends ImageView {
    Paint mPaint;
    float progress;
    boolean isAnimate;
    int rotateProgress;
    Handler mHandler = new Handler();

    public EyeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        rotateProgress = 0;
        progress = 0.0f;
    }

    @Override
    public void onDraw(Canvas canvas) {
        int minWidth = (int) (this.getWidth() * progress);
        int minHeight = (int) (this.getHeight() * progress);
        if (minWidth > 1 && minHeight > 1) {
            Bitmap bitmap = getBitmap();
            canvas.drawBitmap(bitmap, 0, 0, null);
            bitmap.recycle();

        }
    }

    public Bitmap getBitmap() {
        Bitmap origin1 = null;
        Bitmap origin2 = null;
        if (progress >= 1.0) {
            BitmapDrawable drawable1 = (BitmapDrawable) this.getResources()
                    .getDrawable(R.drawable.eye_light1);
            origin1 = drawable1.getBitmap();
            BitmapDrawable drawable2 = (BitmapDrawable) this.getResources()
                    .getDrawable(R.drawable.eye_light2);
            origin2 = drawable2.getBitmap();
        } else {
            BitmapDrawable drawable1 = (BitmapDrawable) this.getResources()
                    .getDrawable(R.drawable.eye_gray_1);
            origin1 = drawable1.getBitmap();
            BitmapDrawable drawable2 = (BitmapDrawable) this.getResources()
                    .getDrawable(R.drawable.eye_gray_2);
            origin2 = drawable2.getBitmap();
        }
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        float scale = (float) origin1.getWidth() / (float) getWidth();
        int maxWidth = (int) (origin1.getWidth() / scale);
        int maxHeight = (int) (origin1.getHeight() / scale);

        int maskSize = 1;

        if (progress > 0.3f) {
            maskSize = (int) (maxHeight * (progress - 0.3) / 0.7);
        }

        Bitmap temp1 = Bitmap.createScaledBitmap(origin1, (int) (maxWidth),
                (int) (maxHeight), true);

        Canvas canvas = new Canvas();
        Bitmap mask = Bitmap.createBitmap(temp1.getWidth(), temp1.getWidth(),
                Config.ARGB_8888);
        canvas.setBitmap(mask);
        canvas.drawCircle(mask.getWidth() / 2, mask.getHeight() / 2, maskSize,
                mPaint);

        Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(),
                Config.ARGB_8888);
        canvas.setBitmap(bitmap);
        canvas.drawBitmap(temp1, (getWidth() - temp1.getWidth()) / 2,
                (getHeight() - temp1.getHeight()) / 2, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        canvas.drawBitmap(mask, (getWidth() - mask.getWidth()) / 2,
                (getHeight() - mask.getHeight()) / 2, paint);
        paint.setXfermode(null);

        float scaleProgress = progress / 0.3f;
        if (scaleProgress > 1.0f) {
            scaleProgress = 1.0f;
        }
        Bitmap temp2 = Bitmap.createScaledBitmap(origin2,
                (int) (maxWidth * scaleProgress),
                (int) (maxHeight * scaleProgress), true);
        Matrix matrix = new Matrix();
        matrix.postRotate(rotateProgress);
        temp2 = Bitmap.createBitmap(temp2, 0, 0, temp2.getWidth(),
                temp2.getHeight(), matrix, false);
        canvas.drawBitmap(temp2, (getWidth() - temp2.getWidth()) / 2,
                (getHeight() - temp2.getHeight()) / 2, paint);

        temp1.recycle();
        temp2.recycle();
        mask.recycle();
        return bitmap;
    }

    public void setProgress(float progress) {
        this.progress = progress;
        this.invalidate();
    }

    public void startAnimate() {
        if (!isAnimate) {
            isAnimate = true;
            // mHandler.post(mRunnable);
        } 
    }

    public void stopAnimate() { 
        isAnimate = false;
        // mHandler.removeCallbacks(mRunnable);
        rotateProgress = 0;
    }

    public Runnable mRunnable = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            rotateProgress += 10;
            if (rotateProgress > 360) {
                rotateProgress = 0;
            }

            if (isAnimate) {
                mHandler.postDelayed(this, 10);
            }
            EyeView.this.invalidate();
        } 
    }; 
}
  • 再看下消息列表界面,监听Listview下拉的高度,来绘制EyeView,并打开视频录制界面。
package com.example.wechat01;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

import com.example.wechat01.adpter.NewMsgAdpter;
import com.example.wechat01.widght.EyeView;
import com.example.wechat01.widght.PullDownListView;
import com.example.wechat01.widght.PullDownListView.OnPullHeightChangeListener;
import com.yixia.camera.demo.ui.record.MediaRecorderActivity;

/**
 * 消息界面
 * 
 * @author allenjuns@yahoo.com
 *
 */
public class Fragment_Msg extends Fragment {
    private Activity ctx;
    private View layout;
    private ListView listview;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        if (layout == null) {
            ctx = this.getActivity();
            layout = ctx.getLayoutInflater().inflate(R.layout.framen_msg, null);
            initView();
            initPullDownView();
        } else {
            ViewGroup parent = (ViewGroup) layout.getParent();
            if (parent != null) {
                parent.removeView(layout);
            }
        }
        return layout;
    }

    private void initView() {
        // TODO 实现本页面的布局 
    }

    private void initPullDownView() {
        final PullDownListView pullDownListView = (PullDownListView) layout
                .findViewById(R.id.pullDownListView);
        final EyeView eyeView = (EyeView) layout.findViewById(R.id.eyeView);

        pullDownListView.getListView().setAdapter(
                new NewMsgAdpter(getActivity()));

        pullDownListView
                .setOnPullHeightChangeListener(new OnPullHeightChangeListener() {

                    @Override
                    public void onTopHeightChange(int headerHeight,
                            int pullHeight) {
                        // TODO Auto-generated method stub
                        float progress = (float) pullHeight
                                / (float) headerHeight;

                        if (progress < 0.5) {
                            progress = 0.0f;
                        } else {
                            progress = (progress - 0.5f) / 0.5f;
                        }

                        if (progress > 1.0f) {
                            progress = 1.0f;
                        }

                        if (!pullDownListView.isRefreshing()) {
                            eyeView.setProgress(progress);
                        }
                    }

                    @Override
                    public void onBottomHeightChange(int footerHeight,
                            int pullHeight) {
                        // TODO Auto-generated method stub
                        float progress = (float) pullHeight
                                / (float) footerHeight;

                        if (progress < 0.5) {
                            progress = 0.0f;
                        } else {
                            progress = (progress - 0.5f) / 0.5f;
                        } 
                        if (progress > 1.0f) {
                            progress = 1.0f;
                        } 
                        if (!pullDownListView.isRefreshing()) { 
                        } 
                    }

                    @Override
                    public void onRefreshing(final boolean isTop) {
                        // TODO Auto-generated method stub
                        if (isTop) {
                            eyeView.startAnimate();
                        } else {
                            // progressView.startAnimate();
                        }
                        // 打开视频录制页面
                        Intent intent = new Intent(ctx,
                                MediaRecorderActivity.class);
                        ctx.startActivity(intent); ctx.overridePendingTransition(R.anim.push_up_in,
                                R.anim.push_up_out);
                        pullDownListView.pullUp();
                    }

                });

        pullDownListView.getListView().setOnItemClickListener(
                new OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> arg0, View arg1,
                            int arg2, long arg3) {
                        // TODO Auto-generated method stub 
                    } 
                }); 
    } 
}

这个Demo比较复杂,具体实现方式请大家去Github研究一下代码吧~ 
另外还有视频录制这块的功能,有些复杂,这块是用的秒拍团队提供的视频录制SDK,感兴趣的可以去官网膜拜~

官网地址: 

OK,项目的完整代码可以去 Github (点击这里) 下载。

本系列文章会教你一步步打造自己的高仿微信APP,尽请关注本博客!

posted @ 2015-09-29 09:57  MyLar  阅读(263)  评论(0)    收藏  举报