編輯:關於Android編程
最近工作繁忙,一直都埋頭在工作中,也不知這麼熱心工作究竟是為了什麼,不知不覺的,到今天才曉得夏天已經來了。天氣熱,心也熱。
網絡上出個牛人,辭職信上寫著:世界那麼大,我想去看看。由衷的佩服她的勇氣,我也想去看看這大千世界,可惜我們總是身不由己,有太多的放不下,或許哪天放下了,我也出去走走。
之前一直以為羅永浩是個逗比,直到前兩天看了他幾期演講,才發現逗比一直是我。他有句話我很欣賞,這裡也分享給大家:在什麼樣的年紀,就做什麼樣的事情,怎麼能在每個階段都做錯呢!PS:該玩的年紀玩,該談戀愛的年紀談戀愛,該成家立業擔起一個家的年紀就要挺起胸膛,總不能錯過玩的年紀,錯過談戀愛的年紀,而成家後卻又搞外遇,怎麼能在每個階段都做錯呢?
在我有那個勇氣也在辭職信上寫著“世界那麼大,我也想去看看!”之前,還是要把眼前的事情做完,現在開始規劃。
正文
Android進度條是很多人都接觸到的,然而面對各種各樣的需求時,原生的很多東西都滿足不了我們的需要,在各種壓迫下,大家都選擇自定義來解決問題。今天給大家介紹一下自定義進度條。
提到自定義,這曾經一直是使我頭疼的問題,看過很多大牛的源碼之後,發現一個道理,有些代碼不應該記住,而有些代碼也不應該忘記。所以我決定,今天的博客裡給大家分享方法。(其實是代碼邏輯實在是太糟糕了,我寫過後回頭看的時候都不知道自己為什麼那麼寫,而且還必須那麼寫,哈哈。)
首先我們要知道自定義View中那些方法是我們需要用到的。
構造方法:
構造方法是必不可少的,所有在View對象一出來就需要存在的都要在這裡初始化。這裡就不多說了。
onDraw
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
}
onSizeChanged
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
}
以上這三個,就可以完成常規的自定義組件,往往我們的業務邏輯上,需要加上很多事件,比如onclick,ontouch等。用到這些事件監聽時,通常需要invalidate方法來在需要的時候刷新界面。
需要注意的是,每個方法的執行順序,建議大家自己用log日志實驗一下。方便記憶。
接下來開始貼代碼,現在大多數需求都是圓角進度條,這裡也以此為例。
onDraw方法是用來繪制任何我們需要的東西的,所以進度條也在此繪制,我將進度條矩形抽取出一個方法,方便復用。
/**
* 繪制矩形
*
* @param canvas
* @param paint
* @param left
* 左
* @param top
* 上
* @param right
* 右
* @param bottom
* 下
*/
private void drawRect(Canvas canvas, Paint paint, float left, float top, float right, float bottom) {
RectF rectF = new RectF(left, top, right, bottom);
if (isRoundRect) {
canvas.drawRoundRect(rectF, mRadius, mRadius, paint);
} else {
canvas.drawRect(rectF, paint);
}
}
好了,我們的自定義進度條講完了。
但是這也就是純粹的進度條了,需要對應的set和get方法來設置和獲取值。set後,記得調用invalidate方法來重繪界面。
我的進度條有拖拽功能,先繪制拖拽的圓圈。
/**
* 繪制拖動點
* @param canvas
*/
private void drawDragClick(Canvas canvas) {
mDragClickPaint.setColor(Color.BLACK);
RectF oval = new RectF(mAboveProgressWidth - mDragClickPaintRadius, mStartY + mProgressRealHeight/2 - mDragClickPaintRadius, mAboveProgressWidth + mDragClickPaintRadius, mStartY + mProgressRealHeight/2 + mDragClickPaintRadius);
canvas.drawOval(oval, mDragClickPaint);
mDragClickPaint.setColor(Color.WHITE);
RectF oval2 = new RectF(mAboveProgressWidth - mDragClickPaintRadius + 1, mStartY + mProgressRealHeight/2 - mDragClickPaintRadius + 1, mAboveProgressWidth + mDragClickPaintRadius - 1, mStartY + mProgressRealHeight/2 + mDragClickPaintRadius - 1);
canvas.drawOval(oval2, mDragClickPaint);
}
private boolean isActionUp;
@Override
public boolean onTouch(View v, MotionEvent event) {
int code = event.getAction();
// Log.i("progress", "onTouch"+mAboveProgressWidth);
switch (code) {
case MotionEvent.ACTION_DOWN:
isActionUp = false;
setOnTouchInit(event);
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
isActionUp = true;
setOnTouchInit(event);
break;
case MotionEvent.ACTION_MOVE:
isActionUp = false;
setOnTouchInit(event);
break;
}
return true;
}
/**
* 觸摸時設置邊界
*/
private void setOnTouchInit(MotionEvent event){
if (isTransfer) {
if (event.getX() < mDragClickPaintRadius) {
mAboveProgressWidth = mDragClickPaintRadius;
}else if (event.getX() > mCenterProgressWidth) {
mAboveProgressWidth = mCenterProgressWidth;
// Log.i("progress", "onTouch"+mAboveProgressWidth + "***" + mCenterProgressWidth);
}else {
mAboveProgressWidth = event.getX();
}
}else {
if (event.getX() < mDragClickPaintRadius) {
mAboveProgressWidth = mDragClickPaintRadius;
}else if (event.getX() > mWidth - mDragClickPaintRadius) {
mAboveProgressWidth = mWidth - mDragClickPaintRadius;
}else {
mAboveProgressWidth = event.getX();
}
}
mFirstValue = mMaxValue *( mAboveProgressWidth - mDragClickPaintRadius) / mDrawScaleWidth;
if (mDragListener != null && isActionUp) {
mDragListener.onDrag(this, getmFirstValue());
}
invalidate();
}
貼上全部的控件代碼
package com.qiyuan.activity.view;
import java.util.Collections;
import java.util.List;
import android.R.integer;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.View.OnClickListener;
/**
* 可以拖動的進度條
*
* @author lizhipeng
*
*/
public class CanDragProgressView extends View implements OnTouchListener,OnClickListener{
private int mWidth, mHeight;// 整個的寬和高
private long mDrawScaleWidth;// 畫刻度時用的寬度(兩邊減去拖動點半徑的寬度)
private int mScaleHeight = 10;// 刻度線的高度
private int mProgressHeight;// 進度條的相對高度
private float mProgressRealHeight = 40;//進度條真實高度
private int mAverageScaleNumber = 10;// 設置均分刻度的個數(多少個單位)
private int mScaleLineWidth, mScalerLineHeight;// 刻度線寬高
private int mRadius;// 進度條圓角半徑
private float mDragClickPaintRadius;// 拖動點半徑
private float mStartX;
private float mStartY = 5;
private float mFirstValue;//顯示在拖動條上的值
private float mSecondValue;//第二個值
private float mBgProgressWidth, mCenterProgressWidth, mAboveProgressWidth;// 背景、中間、上層進度條寬度(長度)
private Paint mBackgroundPaint, mCenterPaint, mAbovePaint, mScalePaint, mDragClickPaint;// 背景畫筆,中間層畫筆,上層畫筆、刻度線、拖動點
private boolean isRoundRect = true;// 是否是圓角矩形
private boolean isAverageScale = true;// 是否均分刻度,如果不均分刻度,需要用設置刻度的集合mScaleList
private boolean isDrawScaleUp = false;// 繪制刻度在進度條上或者下,默認是下
private boolean isDrawScale = true;// 是否繪制刻度
private boolean isDrawCenterScale = false;// 是否繪制中間部分的刻度
private boolean isTransfer = false;// 是否是Transfer界面
private float mMaxValue;//最大值
private List mScaleList;
private DragListener mDragListener;//滑動監聽
public interface DragListener{
public void onDrag(CanDragProgressView view,float value);
}
public DragListener getmDragListener() {
return mDragListener;
}
public void setmDragListener(DragListener mDragListener) {
this.mDragListener = mDragListener;
}
public boolean isTransfer() {
return isTransfer;
}
public void setTransfer(boolean isTransfer) {
this.isTransfer = isTransfer;
invalidate();
}
public boolean isDrawCenterScale() {
return isDrawCenterScale;
}
public void setDrawCenterScale(boolean isDrawCenterScale) {
this.isDrawCenterScale = isDrawCenterScale;
invalidate();
}
public float getmSecondValue() {
return mSecondValue;
}
public void setmSecondValue(float mSecondValue) {
this.mSecondValue = mSecondValue;
invalidate();
}
public float getmFirstValue() {
return Float.parseFloat(String.format("%1.2f", mFirstValue));
}
public void setmFirstValue(float mValue) {
this.mFirstValue = mValue;
invalidate();
}
public List getmScaleList() {
return mScaleList;
}
public void setmScaleList(List list) {
Collections.sort(list);
this.mScaleList = list;
invalidate();
}
public float getmProgressRealHeight() {
return mProgressRealHeight;
}
public void setmProgressRealHeight(float mProgressRealHeight) {
this.mProgressRealHeight = mProgressRealHeight;
invalidate();
}
public void setmScaleHeight(int mScaleHeight) {
this.mScaleHeight = mScaleHeight;
invalidate();
}
public boolean isDrowScaleUp() {
return isDrawScaleUp;
}
public void setDrowScaleUp(boolean isDrowScaleUp) {
this.isDrawScaleUp = isDrowScaleUp;
mStartY = mScaleHeight + getFontHeight(mScalePaint) + 5;
invalidate();
}
public int getmAverageScaleNumber() {
return mAverageScaleNumber;
}
public void setmAverageScaleNumber(int mAverageScaleNumber) {
this.mAverageScaleNumber = mAverageScaleNumber;
invalidate();
}
public int getmScaleLineWidth() {
return mScaleLineWidth;
}
public void setmScaleLineWidth(int mScaleLineWidth) {
this.mScaleLineWidth = mScaleLineWidth;
invalidate();
}
public int getmScalerLineHeight() {
return mScalerLineHeight;
}
public void setmScalerLineHeight(int mScalerLineHeight) {
this.mScalerLineHeight = mScalerLineHeight;
invalidate();
}
public boolean isAverageScale() {
return isAverageScale;
}
public void setAverageScale(boolean isAverageScale) {
this.isAverageScale = isAverageScale;
invalidate();
}
// private int getmWidth() {
// return mWidth;
// }
//
// private void setmWidth(int mWidth) {
// this.mWidth = mWidth;
// }
public int getmHeight() {
return mHeight;
}
public void setmHeight(int mHeight) {
this.mHeight = mHeight;
}
public int getmProgressHeight() {
return mProgressHeight;
}
public void setmProgressHeight(int mProgressHeight) {
this.mProgressHeight = mProgressHeight;
invalidate();
}
public int getmRadius() {
return mRadius;
}
public void setmRadius(int mRadius) {
this.mRadius = mRadius;
invalidate();
}
public float getmBgProgressWidth() {
return mBgProgressWidth;
}
public void setmBgProgressWidth(float mBgProgressWidth) {
this.mBgProgressWidth = mBgProgressWidth;
invalidate();
}
public float getmCenterProgressWidth() {
return mCenterProgressWidth;
}
public void setmCenterProgressWidth(float mCenterProgressWidth) {
this.mCenterProgressWidth = mCenterProgressWidth;
invalidate();
}
public float getmAboveProgressWidth() {
return mAboveProgressWidth;
}
public void setmAboveProgressWidth(float mAboveProgressWidth) {
this.mAboveProgressWidth = mAboveProgressWidth;
invalidate();
}
// ------------------------------------------------------------------Paint------------------
public Paint getmDragClickPaint() {
return mDragClickPaint;
}
public void setmDragClickPaint(Paint mDragClickPaint) {
initPain(mDragClickPaint);
this.mDragClickPaint = mDragClickPaint;
invalidate();
}
public Paint getmScalePaint() {
return mScalePaint;
}
public void setmScalePaint(Paint mScalePaint) {
initPain(mScalePaint);
this.mScalePaint = mScalePaint;
invalidate();
}
public Paint getmBackgroundPaint() {
return mBackgroundPaint;
}
public void setmBackgroundPaint(Paint mBackgroundPaint) {
initPain(mBackgroundPaint);
this.mBackgroundPaint = mBackgroundPaint;
invalidate();
}
public Paint getmCenterPaint() {
return mCenterPaint;
}
public void setmCenterPaint(Paint mCenterPaint) {
initPain(mCenterPaint);
this.mCenterPaint = mCenterPaint;
invalidate();
}
public Paint getmAbovePaint() {
return mAbovePaint;
}
public void setmAbovePaint(Paint mAbovePaint) {
initPain(mAbovePaint);
this.mAbovePaint = mAbovePaint;
invalidate();
}
// ------------------------------------------------------------------Paint------------------
public boolean isRoundRect() {
return isRoundRect;
}
public void setRoundRect(boolean isRoundRect) {
this.isRoundRect = isRoundRect;
invalidate();
}
public float getmMaxValue() {
return mMaxValue;
}
public void setmMaxValue(float mMaxValue) {
this.mMaxValue = mMaxValue;
invalidate();
}
public CanDragProgressView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
public CanDragProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
public CanDragProgressView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init();
}
/**
* 初始化
*/
private void init() {
mBackgroundPaint = new Paint();
mBackgroundPaint.setColor(Color.GRAY);
mScalePaint = new Paint();
mScalePaint.setColor(Color.GRAY);
mScalePaint.setTextSize(16);
mCenterPaint = new Paint();
mCenterPaint.setColor(Color.BLUE);
mAbovePaint = new Paint();
mAbovePaint.setColor(Color.RED);
mAbovePaint.setTextSize(45);
mDragClickPaint = new Paint();
mDragClickPaint.setColor(Color.BLACK);
this.setOnTouchListener(this);
initPain(mDragClickPaint);
initPain(mBackgroundPaint);
initPain(mScalePaint);
initPain(mCenterPaint);
initPain(mAbovePaint);
}
/**
* 初始化畫筆
*
* @param paint
*/
private void initPain(Paint paint) {
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setAntiAlias(true);// 抗鋸齒效果
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(widthMeasureSpec, 150);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
mWidth = w;
mHeight = h;
mBgProgressWidth = mWidth;
mCenterProgressWidth = 2 * mBgProgressWidth / 3;
if (isDrawScaleUp) {
mStartY = mScaleHeight + getFontHeight(mScalePaint) + 5;
mProgressHeight = (int) (getFontHeight(mScalePaint) + mScaleHeight + mProgressRealHeight + 5 + mStartY);
} else {
mStartY = 60;
mProgressHeight = (int) (mProgressRealHeight + mStartY);
}
mDragClickPaintRadius = (float) (mProgressRealHeight / 2 + 15);
mRadius = (int) (mProgressRealHeight / 2 + 5);
mDrawScaleWidth = (long) (mWidth - 2 * mDragClickPaintRadius);
mScaleHeight = 10;
mAboveProgressWidth = (mDrawScaleWidth*(mFirstValue/mMaxValue) + mDragClickPaintRadius);
mCenterProgressWidth = (mDrawScaleWidth*(mSecondValue/mMaxValue) + mDragClickPaintRadius);
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
// 繪制三個矩形
drawRect(canvas, mBackgroundPaint, 0, mStartY, mBgProgressWidth, mProgressHeight);
// Log.i("progress", mBgProgressWidth+"**"+mProgressHeight+"**"+mStartY+"**"+getFontHeight(mScalePaint));
drawRect(canvas, mCenterPaint, 0, mStartY, mCenterProgressWidth, mProgressHeight);
drawRect(canvas, mAbovePaint, 0, mStartY, mAboveProgressWidth, mProgressHeight);
// 繪制刻度
drawScales(canvas);
// 繪制拖動點
drawDragClick(canvas);
// 繪制滾動數字
drawChangeValue(canvas);
super.onDraw(canvas);
}
/**
* 繪制滾動數字
* @param canvas
*/
private void drawChangeValue(Canvas canvas) {
if (mAbovePaint.measureText(String.format("%1.2f", mFirstValue)) + mDrawScaleWidth*mFirstValue/mMaxValue > mWidth) {
canvas.drawText(String.format("%1.2f", mFirstValue), mWidth - mAbovePaint.measureText(String.format("%1.2f", mFirstValue)), 3*getFontHeight(mAbovePaint)/4, mAbovePaint);
}else {
canvas.drawText(String.format("%1.2f", mFirstValue), mDrawScaleWidth*mFirstValue/mMaxValue, 3*getFontHeight(mAbovePaint)/4, mAbovePaint);
}
}
/**
* 繪制拖動點
* @param canvas
*/
private void drawDragClick(Canvas canvas) {
mDragClickPaint.setColor(Color.BLACK);
RectF oval = new RectF(mAboveProgressWidth - mDragClickPaintRadius, mStartY + mProgressRealHeight/2 - mDragClickPaintRadius, mAboveProgressWidth + mDragClickPaintRadius, mStartY + mProgressRealHeight/2 + mDragClickPaintRadius);
canvas.drawOval(oval, mDragClickPaint);
mDragClickPaint.setColor(Color.WHITE);
RectF oval2 = new RectF(mAboveProgressWidth - mDragClickPaintRadius + 1, mStartY + mProgressRealHeight/2 - mDragClickPaintRadius + 1, mAboveProgressWidth + mDragClickPaintRadius - 1, mStartY + mProgressRealHeight/2 + mDragClickPaintRadius - 1);
canvas.drawOval(oval2, mDragClickPaint);
}
/**
* 繪制刻度
*
* @param canvas
*/
private void drawScales(Canvas canvas) {
if (isDrawScale) {// 是否繪制刻度
if (isAverageScale) {// 均分的刻度
long unitLenght = mDrawScaleWidth / mAverageScaleNumber;// 單位長度
if (isDrawScaleUp) {
for (int i = 0; i < mAverageScaleNumber + 1; i++) {
float startX = mDragClickPaintRadius + i * unitLenght;
canvas.drawLine(startX, getFontHeight(mScalePaint), startX, mScaleHeight +getFontHeight(mScalePaint), mScalePaint);
canvas.drawText(mMaxValue/mAverageScaleNumber*i+"", startX - mScalePaint.measureText(startX + "") / 2, getFontHeight(mScalePaint), mScalePaint);
}
} else {
for (int i = 0; i < mAverageScaleNumber + 1; i++) {
if (isDrawCenterScale) {
float startX = mDragClickPaintRadius + i * unitLenght;
float endY = mProgressHeight + 5 + mScaleHeight;
canvas.drawLine(startX, mProgressHeight + 5, startX, endY, mScalePaint);
canvas.drawText(mMaxValue/mAverageScaleNumber*i+"", startX - mScalePaint.measureText(startX + "") / 3, endY + getFontHeight(mScalePaint), mScalePaint);
}else {
if (i == 0 || i == mAverageScaleNumber) {
float startX = mDragClickPaintRadius + i * unitLenght;
float endY = mProgressHeight + 5 + mScaleHeight;
canvas.drawLine(startX, mProgressHeight + 5, startX, endY, mScalePaint);
canvas.drawText(mMaxValue/mAverageScaleNumber*i+"", startX - mScalePaint.measureText(startX + "") / 3, endY + getFontHeight(mScalePaint), mScalePaint);
}
}
}
}
} else {
if (isDrawScaleUp) {
for (int i = 0; i < mScaleList.size(); i++) {
double number = mScaleList.get(i);
double unit = mDrawScaleWidth*(number/mMaxValue);
float startX = (float) (mDragClickPaintRadius + unit);
if (unit != 0) {
canvas.drawLine(mDragClickPaintRadius, getFontHeight(mScalePaint), mDragClickPaintRadius, mScaleHeight +getFontHeight(mScalePaint), mScalePaint);
canvas.drawText("0", mDragClickPaintRadius - mScalePaint.measureText("0") / 2, getFontHeight(mScalePaint), mScalePaint);
}
canvas.drawLine(startX, getFontHeight(mScalePaint), startX, mScaleHeight +getFontHeight(mScalePaint), mScalePaint);
canvas.drawText(mScaleList.get(i)+"", startX - mScalePaint.measureText(""+mScaleList.get(i))/2, getFontHeight(mScalePaint), mScalePaint);
}
} else {
for (int i = 0; i < mScaleList.size(); i++) {
double number = mScaleList.get(i);
double unit = mDrawScaleWidth*(number/mMaxValue);
float startX = (float) (mDragClickPaintRadius + unit);
float endY = mProgressHeight + 5 + mScaleHeight;
if (unit != 0) {
canvas.drawLine(mDragClickPaintRadius, mProgressHeight + 5, mDragClickPaintRadius, endY, mScalePaint);
canvas.drawText("0", mDragClickPaintRadius - mScalePaint.measureText("0") / 2, endY + getFontHeight(mScalePaint), mScalePaint);
}
canvas.drawLine(startX, mProgressHeight + 5, startX, endY, mScalePaint);
canvas.drawText(mScaleList.get(i)+"", startX - mScalePaint.measureText(""+mScaleList.get(i))/2, endY + getFontHeight(mScalePaint), mScalePaint);
}
}
}
}
}
/**
* 繪制矩形
*
* @param canvas
* @param paint
* @param left
* 左
* @param top
* 上
* @param right
* 右
* @param bottom
* 下
*/
private void drawRect(Canvas canvas, Paint paint, float left, float top, float right, float bottom) {
RectF rectF = new RectF(left, top, right, bottom);
if (isRoundRect) {
canvas.drawRoundRect(rectF, mRadius, mRadius, paint);
} else {
canvas.drawRect(rectF, paint);
}
}
/**
* 獲取繪制的字體高度
*
* @param paint
* @return
*/
private int getFontHeight(Paint paint) {
FontMetrics fm = paint.getFontMetrics();
return (int) Math.ceil(fm.descent - fm.ascent);
}
private boolean isActionUp;
@Override
public boolean onTouch(View v, MotionEvent event) {
int code = event.getAction();
// Log.i("progress", "onTouch"+mAboveProgressWidth);
switch (code) {
case MotionEvent.ACTION_DOWN:
isActionUp = false;
setOnTouchInit(event);
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
isActionUp = true;
setOnTouchInit(event);
break;
case MotionEvent.ACTION_MOVE:
isActionUp = false;
setOnTouchInit(event);
break;
}
return true;
}
/**
* 觸摸時設置邊界
*/
private void setOnTouchInit(MotionEvent event){
if (isTransfer) {
if (event.getX() < mDragClickPaintRadius) {
mAboveProgressWidth = mDragClickPaintRadius;
}else if (event.getX() > mCenterProgressWidth) {
mAboveProgressWidth = mCenterProgressWidth;
// Log.i("progress", "onTouch"+mAboveProgressWidth + "***" + mCenterProgressWidth);
}else {
mAboveProgressWidth = event.getX();
}
}else {
if (event.getX() < mDragClickPaintRadius) {
mAboveProgressWidth = mDragClickPaintRadius;
}else if (event.getX() > mWidth - mDragClickPaintRadius) {
mAboveProgressWidth = mWidth - mDragClickPaintRadius;
}else {
mAboveProgressWidth = event.getX();
}
}
mFirstValue = mMaxValue *( mAboveProgressWidth - mDragClickPaintRadius) / mDrawScaleWidth;
if (mDragListener != null && isActionUp) {
mDragListener.onDrag(this, getmFirstValue());
}
invalidate();
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
Android實現應用內置語言切換功能
一、需求有時候應用需要在內部切換語言但又不影響系統的語言,比如是應用現在是中文的,系統語言也是中文的,我把應用的切換成英文顯示後系統語言還是中文的,系統語言切換後也不會被
[Android] 使用Include布局+Fragment滑動切換屏幕
前面的文章已經講述了隨手拍項目圖像處理的技術部分,該篇文章主要是主界面的布局及屏幕滑動切換,並結合鴻洋大神的視頻和郭神的第一行代碼(強推兩人Android博客),完成了下
Android 增量升級學習使用記錄
好久沒有發博客了,現在工作忙了,底層代碼跟蹤學習的東西很久沒有做成文檔了,雖然博客寫的爛,但是再寫的過程中,能更清晰的認識到自己那個地方還不清晰,不明白。這樣能更好的嘴一
Android UI效果之繪圖篇(四)
上一篇博文說到了Shader的五個子類 - BitmapShader - LinearGradient - RadialGradient - SweepGradient