Android实现步进式录像进度条
2015-09-10 17:32
218 查看
现在的APP对用户的体验要求越来越高,操作简单、样式新颖的交互能够提高用户的黏性。今天来实现一下步进式录像进度条,秒拍中用到这样的进度条,如下图:
下面来简单实现一下:
activity_main.xml
下面来简单实现一下:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <RelativeLayout android:id="@+id/progress_layout" android:layout_width="match_parent" android:layout_height="wrap_content" > <com.jackie.steppingprogressbar.SteppingProgressBar android:id="@+id/stepping_progressbar" android:layout_width="match_parent" android:layout_height="50dp" /> </RelativeLayout> <LinearLayout android:id="@+id/button_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/progress_layout" android:layout_marginTop="30dp" > <Button android:id="@+id/btn_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15dp" android:onClick="onStartClick" android:text="开始" /> <Button android:id="@+id/btn_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:onClick="onStopClick" android:text="停止" /> <Button android:id="@+id/btn_reset" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:onClick="onResetClick" android:text="重置" /> <Button android:id="@+id/btn_delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:onClick="onDeleteClick" android:text="删除" /> </LinearLayout> </RelativeLayout>SteppingProgressBar.java
package com.jackie.steppingprogressbar; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Rect; import android.graphics.Typeface; import android.util.AttributeSet; import android.view.View; public class SteppingProgressBar extends View { private Paint mPaint; private int mMaxWidth; private float mPercent = 0; private boolean mIsProgressPause; private boolean mAddTimeStamp; private List<Rect> mTimeStampPosition = new ArrayList<Rect>(); private List<Float> mTimeStampPercent = new ArrayList<Float>(); private final int STATE_NORMAL = 1; private final int STATE_DELETE_PREPARE = 2; private final int STATE_DELETE_DONE = 3; private int mState = STATE_NORMAL; private int MAX_PERCENT = 100; private final static int PROGRESS_TEXT_SIZE = 56; private final static int PROGRESS_SCALE = 1000; private final static int PROGRESS_BACKGROUND_COLOR = Color.parseColor("#66030e18"); private final static int PROGRESS_PASSED_COLOR = Color.parseColor("#7cb855"); private final static int PROGRESS_STAMP_COLOR = Color.parseColor("#4a7b17"); private final static int PROGRESS_TEXT_COLOR = Color.parseColor("#ff0000"); private final static int PROGRESS_DELETING_COLOR = Color.parseColor("#3c6e57"); private SteppingProgressBarCallbackListener mSteppingProgressBarCallbackListener = null; public void setOnDeleteCallbackListener(SteppingProgressBarCallbackListener listener) { this.mSteppingProgressBarCallbackListener = listener; } public interface SteppingProgressBarCallbackListener { /* 删除完成的回调 */ public void deleteDone(float percent); } public SteppingProgressBar(Context context, AttributeSet attrs) { super(context, attrs); initData(); } private void initData() { mPaint = new Paint(); mPaint.setAlpha(255); mPaint.setStyle(Style.FILL); mPaint.setDither(true); //防抖动 mPaint.setAntiAlias(true); //放锯齿 } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //获取尺寸 int size = MeasureSpec.getSize(heightMeasureSpec); size = (int)(size + PROGRESS_TEXT_SIZE + 10); heightMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制底色 mPaint.setColor(PROGRESS_BACKGROUND_COLOR); float width = mMaxWidth = getWidth(); float height = getHeight() - PROGRESS_TEXT_SIZE - 10; canvas.drawRect(0, 0, width, height, mPaint); //绘制进度色 mPaint.setColor(PROGRESS_PASSED_COLOR); width = (float) mPercent / (float) MAX_PERCENT * width; canvas.drawRect(0, 0, width, height, mPaint); //在下次进度条重新开始时,计算上次的分隔条 if (mAddTimeStamp && mState == STATE_NORMAL && !mIsProgressPause) { mAddTimeStamp = false; Rect mRect = new Rect(); mRect.left = (int) (width - 4); mRect.top = 0; mRect.right = (int) width; mRect.bottom = (int) height; mTimeStampPosition.add(mRect); mTimeStampPercent.add(mPercent); } //绘制所有分隔条 for (Rect mRect : mTimeStampPosition) { mPaint.setColor(PROGRESS_STAMP_COLOR); canvas.drawRect(mRect, mPaint); } //绘制进度值文本 mPaint.setStrokeWidth(0); mPaint.setColor(PROGRESS_TEXT_COLOR); mPaint.setTextSize(PROGRESS_TEXT_SIZE); mPaint.setTypeface(Typeface.DEFAULT); float textWidth = mPaint.measureText(mPercent / PROGRESS_SCALE + "s"); if (mPercent != 0) { if (width + textWidth > mMaxWidth) { canvas.drawText(mPercent / PROGRESS_SCALE + "s", (width - textWidth), height + PROGRESS_TEXT_SIZE, mPaint); } else { canvas.drawText(mPercent / PROGRESS_SCALE + "s", width, height + PROGRESS_TEXT_SIZE, mPaint); } } if (mState == STATE_DELETE_DONE) { mState = STATE_NORMAL; //当删除完成时,准备绘制本次分隔条,当percent为0的时候不绘制 if (mPercent != 0) { this.mAddTimeStamp = true; } } else if (mState == STATE_DELETE_PREPARE) { //当准备删除时,将上段时间内的进度条变色 mPaint.setColor(PROGRESS_DELETING_COLOR); int left; if (mTimeStampPosition != null && mTimeStampPosition.size() > 0) { left = mTimeStampPosition.get(mTimeStampPosition.size() -1).right; } else { left = 0; } canvas.drawRect(left, 0, width, height, mPaint); } } /** * 进度条的最大值 * @param maxPercent */ public void setMax(int maxPercent) { this.MAX_PERCENT = maxPercent; } /** * 当前进度 * @return */ public float getProgress() { return mPercent; } /** * 设置当前进度 * @param percent */ public void setProgress(float percent) { if (percent < 0) { return; } if (percent >= MAX_PERCENT) { percent = MAX_PERCENT; } this.mPercent = percent; this.mState = STATE_NORMAL; this.mIsProgressPause = false; invalidate(); } /** * 设置视频录制中间的断点时间戳 * @param timeStamp */ public void setTimeStamp(boolean timeStamp) { this.mIsProgressPause = true; this.mAddTimeStamp = timeStamp; } /** * 准备删除前一段进度 */ public void deleteLastStepPrepare() { if (mState == STATE_DELETE_PREPARE) { return; } mState = STATE_DELETE_PREPARE; invalidate(); } /** * 确认删除前一段进度 */ public void deleteLastStep() { if (mState != STATE_DELETE_PREPARE) { deleteLastStepPrepare(); return; } if (mTimeStampPercent != null && mTimeStampPercent.size() > 0) { this.mPercent = mTimeStampPercent.remove(mTimeStampPercent.size() - 1); } else { this.mPercent = 0; } this.mAddTimeStamp = false; mState = STATE_DELETE_DONE; //操作断点 if (mTimeStampPosition != null && mTimeStampPosition.size() > 0) { mTimeStampPosition.remove(mTimeStampPosition.size() - 1); } if (mSteppingProgressBarCallbackListener != null) { mSteppingProgressBarCallbackListener.deleteDone(this.mPercent); } invalidate(); } /** * 取消删除前一段进度 */ public void deleteLastStepCancel() { if (mState == STATE_NORMAL) { return; } mState = STATE_DELETE_DONE; invalidate(); } /** * 重置进度条 */ public void reset() { this.mPercent = 0; this.mAddTimeStamp = false; mTimeStampPosition.clear(); mTimeStampPercent.clear(); invalidate(); } }MainActivity.java
package com.jackie.steppingprogressbar; import com.jackie.steppingprogressbar.SteppingProgressBar.SteppingProgressBarCallbackListener; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Menu; import android.view.View; public class MainActivity extends Activity { SteppingProgressBar mProgressBar; private boolean mIsStopped = true; private int mProgress; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); setProgress(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mProgressBar = (SteppingProgressBar) findViewById(R.id.stepping_progressbar); mProgressBar.setMax(10000); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. // getMenuInflater().inflate(R.menu.main, menu); return true; } public void onStartClick(View view) { if (!mIsStopped) { return; } mIsStopped = false; mHandler.removeMessages(0); mHandler.sendEmptyMessage(0); } private void setProgress() { if (mProgress > 10000) { mHandler.removeMessages(0); } else if (!mIsStopped) { mProgress += 100; mProgressBar.setProgress(mProgress); mHandler.sendEmptyMessageDelayed(0, 100); } } public void onStopClick(View view) { mIsStopped = true; mProgressBar.setTimeStamp(true); } public void onResetClick(View view) { mProgressBar.reset(); mProgress = 0; } public void onDeleteClick(View view) { if (!mIsStopped) { return; } mProgressBar.deleteLastStep(); mProgressBar.setOnDeleteCallbackListener(new SteppingProgressBarCallbackListener() { @Override public void deleteDone(float percent) { mProgress = (int) percent; } }); } }效果图如下:
相关文章推荐
- android 相机与手电筒的互斥
- adb详解
- Android中调用Web Services
- adb详解
- Android RecyclerView 使用完全解析 体验艺术般的控件
- 小笔记 使android界面打开时EditText不自动获得焦点
- Android与服务器端数据交互
- Android library projects cannot be launched
- 安卓错误E/AndroidRuntime(4054):java.lang.NullPointerException
- 初识android vector drawable
- android屏幕适配方案 - dimen生成器
- RGB 颜色对照表
- Android 国际化 语言适配
- Android的任务和回退栈
- Android adb无法启动
- Android视频录制--MediaProjection
- Android Property Animation 属性动画
- Android Cursor类的概念和用法
- [Android]最省内存的ViewPager添加小圆点指示器
- 从头到尾详解Android Studio