日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Android實現繪畫板功能

瀏覽:32日期:2022-09-18 14:07:55
目錄實現流程:實現步驟:一、預期效果二、設置橫豎屏切換三、確定布局四、自定義滑動條五、繪畫區域六、MainActivity實現流程:

一、預期效果二、設置橫豎屏切換三、確定布局四、自定義滑動條五、繪畫區域六、MainActivity

實現步驟:一、預期效果

Android實現繪畫板功能

二、設置橫豎屏切換

screenOrientation屬性        作用 user 用戶當前設置的方向。 unspecified 由系統選擇顯示方向,不同的設備可能會有所不同。(旋轉手機,界面會跟著旋轉) landscape 限制界面為橫屏,旋轉屏幕也不會改變當前狀態。 portrait 限制界面為豎屏,旋轉屏幕也不會改變當前狀態。 behind 與前一個activity方向相同。 sensor 根據傳感器定位方向,旋轉手機90度,180,270,360,界面都會發生變化。 nosensor 不由傳感器確定方向。旋轉設備的時候,界面不會跟著旋轉。初始界面方向由系統提供。 sensorLandscape (橫屏的旋轉,不會出現豎屏的現象)根據傳感器定位方向,旋轉手機180度界面旋轉。一般橫屏游戲會是這個屬性。 sensorPortrait (豎屏的旋轉,不會出現橫屏的現象)根據傳感器定位方向,旋轉手機180度界面會旋轉。

三、確定布局

因為橫豎屏切換后控件的寬高都是不一樣的,也就是不固定的,不能用線性布局,而是根據相對位置進行布局。先用constraintLayout約束,再將小控件組合成一個線性布局,然后對整個線性布局進行相對布局。

Android實現繪畫板功能

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android='http://schemas.android.com/apk/res/android' xmlns:app='http://schemas.android.com/apk/res-auto' xmlns:tools='http://schemas.android.com/tools' android:layout_width='match_parent' android:layout_height='match_parent' tools:context='.MainActivity'> <androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width='match_parent'android:layout_height='0dp'app:layout_constraintTop_toTopOf='parent'app:layout_constraintBottom_toTopOf='@id/operation'><!--滑動條--><com.example.a16drawboard.Slider android: android:layout_width='20dp' android:layout_height='match_parent' android:layout_marginLeft='20dp' android:layout_marginTop='20dp' android:layout_marginBottom='20dp' app:layout_constraintLeft_toLeftOf='parent' /><!--畫板--><com.example.a16drawboard.DrawBoardView android: android:layout_width='0dp' android:layout_height='match_parent' app:layout_constraintLeft_toRightOf='@id/slider' app:layout_constraintRight_toLeftOf='@id/color'/> <!--選顏色--><LinearLayout android: android:layout_width='60dp' android:layout_height='match_parent' android:orientation='vertical' android:layout_marginRight='20dp' app:layout_constraintRight_toRightOf='parent' android:gravity='center'> <Buttonandroid:layout_width='match_parent'android:layout_height='50dp'android:background='@color/colorAccent'android:onClick='choiceColor'/> <Buttonandroid:layout_width='match_parent'android:layout_height='50dp'android:background='@color/colorPrimary'android:onClick='choiceColor'/> <Buttonandroid:layout_width='match_parent'android:layout_height='50dp'android:background='#f00'android:onClick='choiceColor'/> <Buttonandroid:layout_width='match_parent'android:layout_height='50dp'android:background='#000'android:onClick='choiceColor'/></LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> <LinearLayoutandroid: android:layout_width='match_parent'android:layout_height='60dp'android:background='#f00'android:orientation='horizontal'app:layout_constraintBottom_toBottomOf='parent'android:gravity='center'><Button android:layout_width='70dp' android:layout_height='wrap_content' android:text='撤銷' android:onClick='goBack'/><Button android:layout_width='70dp' android:layout_height='wrap_content' android:text='清空' android:onClick='clear'/><Button android:layout_width='70dp' android:layout_height='wrap_content' android:text='橡皮擦' android:onClick='eraser'/><Button android:layout_width='70dp' android:layout_height='wrap_content' android:text='保存' android:onClick='save'/><Button android:layout_width='70dp' android:layout_height='wrap_content' android:text='上一步' android:onClick='lastStep'/> </LinearLayout></androidx.constraintlayout.widget.ConstraintLayout>四、自定義滑動條

public class Slider extends View { private int lineSize = 6; // 線條的粗細 private int lineColor = Color.BLACK;// 默認線條顏色 private Paint linePaint; private Paint circlePaint; // 圓點畫筆 private int thumbColor = Color.MAGENTA; // 圓點顏色 private int cx; // 中心點x private int cy; // 中心點y private int radius; // 小圓點半徑 private int thumbScale = 4; // 圓點縮放尺寸 private float position; // 觸摸點的坐標 private Paint progressPaint; // 進度條進度的畫筆 private int progressColor = Color.MAGENTA; // 進度條顏色 public static int PROGRESS = 0; // 進度條 public static int SLIDER = 1; // 滑動條 private int style = PROGRESS; // 用戶選擇的樣式,默認為進度條 public int max = 100; // 設置最大值 public float progress; // 進度值 private OnSliderChangeListener onSliderChangeListener; // 滑動改變監聽者 public Slider(Context context) {super(context); } public Slider(Context context, AttributeSet attrs) {super(context, attrs);init(); } private void init(){// 背景線linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);linePaint.setColor(lineColor);linePaint.setStrokeWidth(lineSize);// 圓點circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);circlePaint.setColor(thumbColor);circlePaint.setStyle(Paint.Style.FILL);// 進度條progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);progressPaint.setColor(progressColor);progressPaint.setStrokeWidth(lineSize); } @Override protected void onDraw(Canvas canvas) {if (getWidth() > getHeight()){ // 橫著 canvas.drawLine(0, getHeight()/2, getWidth(), getHeight()/2, linePaint); if (position>0){canvas.drawLine(0, getHeight()/2, position, getHeight()/2, progressPaint); } radius = getHeight()/thumbScale; cy = getHeight()/2; // 確定cx的值 if (position < radius) {cx = radius; }else if (position > getWidth()-radius){cx = getWidth()-radius; }else {cx = (int) position; }}else{ // 豎著 canvas.drawLine(getWidth()/2, 0, getWidth()/2, getHeight(), linePaint); if (position>0){canvas.drawLine(getWidth()/2, 0, getWidth()/2, position, progressPaint); } radius = getWidth()/thumbScale; cx = getWidth()/2; // 確定中心點cy的值 if (position<radius){cy = radius; }else if (position > getHeight()-radius){cy = getHeight()-radius; }else {cy = (int) position; }}// 畫小圓點if (style == SLIDER){ canvas.drawCircle(cx,cy,radius,circlePaint);} } @Override public boolean onTouchEvent(MotionEvent event) {switch (event.getAction()){ case MotionEvent.ACTION_DOWN:// 圓點放大thumbScale = 2;// 點下去就到那個位置if (getWidth()>getHeight()){ // 橫向時,y不變 x改變 position = event.getX();}else { // 縱向時,x不變 y改變 position = event.getY();}callback();break; case MotionEvent.ACTION_MOVE:// 獲取當前觸摸點的值XYif (getWidth()>getHeight()){ // 橫向時,y不變 x改變 position = event.getX(); if (position<0){progress = 0; }else if (position>getWidth()){position = getWidth(); }}else { // 豎著時,x不變 y改變 position = event.getY(); if (position<0){progress = 0; }else if (position>getHeight()){position = getHeight(); }}callback();break; case MotionEvent.ACTION_UP:thumbScale = 4;break;}if (style == SLIDER){ invalidate();}return true; } private void callback(){if (onSliderChangeListener != null){ if (getWidth()>getHeight()){progress = position/getWidth(); }else {progress = position/getHeight(); } onSliderChangeListener.progressChange(progress*max);} } public int getStyle() {return style; } public void setStyle(int style) {this.style = style; } public float getProgress() {return progress; } public void setProgress(int progress){// 計算比例float rate = (float)(progress*1.0/max);setProgress(rate); } public void setProgress(float progress) {this.progress = progress;if (progress <1.001) { // 將進度值轉化為控件中的尺寸位置 if (getWidth() > getHeight()) {position = progress * getWidth(); } else {position = progress * getHeight(); } invalidate();} } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {if (getWidth() > getHeight()) { position = progress * getWidth();} else { position = progress * getHeight();} } public void setMax(int max) {this.max = max; } public interface OnSliderChangeListener{void progressChange(float progress); } public void setOnSliderChangeListener(OnSliderChangeListener onSliderChangeListener) {this.onSliderChangeListener = onSliderChangeListener; }}五、繪畫區域

public class DrawBoardView extends View { private ArrayList<Graph> graphs; // 操作數組 private ArrayList<Graph> orginalGraphs; // 原始數組 private int lineColor = Color.BLACK; private int lineSize = 5; Path mPath; public DrawBoardView(Context context) {super(context); } public DrawBoardView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init(); } private void init(){// 初始化數組graphs = new ArrayList<>();orginalGraphs = new ArrayList<>();setBackgroundColor(Color.WHITE); } @Override protected void onDraw(Canvas canvas) {// 遍歷數組Iterator<Graph> iterator = graphs.iterator();while (iterator.hasNext()){ // 從集合中獲取一個圖形對象 Graph line = iterator.next(); // 繪制圖形 canvas.drawPath(line.path,line.paint);} } @Override public boolean onTouchEvent(MotionEvent event) {switch (event.getAction()){ case MotionEvent.ACTION_DOWN:// 創建這條線對應的paint和pathPaint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(lineColor);mPaint.setStrokeWidth(lineSize);mPaint.setStyle(Paint.Style.STROKE);mPath = new Path();// 設置圖形的起點mPath.moveTo(event.getX(),event.getY());// 保存當前這個圖形的詳細信息Graph temp = new Graph(mPaint,mPath);graphs.add(temp);orginalGraphs.add(temp);break; case MotionEvent.ACTION_MOVE:// 連接從path終點到當前觸摸點的線mPath.lineTo(event.getX(),event.getY());break; case MotionEvent.ACTION_UP:break;}invalidate();return true; } // 用私有類來管理圖形的畫筆和路徑 private class Graph{Paint paint;Path path;public Graph(Paint paint,Path path){ this.paint=paint; this.path=path;} } // 刪除最后一個圖形 撤銷 public void removeLast(){if (graphs.size() >0){ graphs.remove(graphs.size()-1); invalidate();} } // 刪除所有 清空 public void removeAll(){graphs.clear();invalidate(); } // 還原上一步 public void returnToLastStep(){// 判斷緩存中是否有if (graphs.size() < orginalGraphs.size()){ // 獲取上一步的索引值 int index = graphs.size()-1+1; // 從緩存中獲取index,添加到操作數組中 graphs.add(orginalGraphs.get(index)); invalidate();} } public int getLineSize() {return lineSize; } public void setLineSize(int lineSize) {this.lineSize = lineSize; } public int getLineColor() {return lineColor; } public void setLineColor(int lineColor) {this.lineColor = lineColor; }}六、MainActivity

public class MainActivity extends AppCompatActivity { private DrawBoardView boardView; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 獲取畫板對象boardView = findViewById(R.id.board);// 獲取滑動條對象final Slider slider = findViewById(R.id.slider);slider.setStyle(Slider.SLIDER);slider.setMax(30);slider.setOnSliderChangeListener(new Slider.OnSliderChangeListener() { @Override public void progressChange(float progress) {boardView.setLineSize((int) progress); }});slider.setProgress(boardView.getLineSize()); } @Override public void onWindowFocusChanged(boolean hasFocus) {super.onWindowFocusChanged(hasFocus); } @Override protected void onStart() {super.onStart(); } @Override protected void onResume() {super.onResume();// 設置橫屏setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); } @Override protected void onPause() {super.onPause(); } @Override protected void onStop() {super.onStop(); } // 選擇顏色 獲取按鈕上面的背景顏色 public void choiceColor(View view) {// 獲取按鈕上面的背景顏色ColorDrawable drawable = (ColorDrawable) view.getBackground();// 獲取顏色boardView.setLineColor(drawable.getColor()); } // 撤回 public void goBack(View view) {boardView.removeLast(); } // 清空 public void clear(View view) {boardView.removeAll(); } // 橡皮擦 public void eraser(View view) {// 獲取畫板的drawableColorDrawable drawable = (ColorDrawable) boardView.getBackground();// 設置線條顏色和背景色相同if (drawable != null){ boardView.setLineColor(drawable.getColor());}else { boardView.setLineColor(Color.TRANSPARENT);} } // 保存 public void save(View view) { } // 還原 public void lastStep(View view) {boardView.returnToLastStep(); }}

到這里就結束啦。

以上就是Android實現畫板功能的詳細內容,更多關于Android 畫板功能的資料請關注好吧啦網其它相關文章!

標簽: Android
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
美女少妇全过程你懂的久久| 国产一区二区三区视频在线| 三级小说欧洲区亚洲区| 日韩欧美一区二区三区在线视频| 激情不卡一区二区三区视频在线| 电影91久久久| 88xx成人免费观看视频库| 欧美日韩精品在线一区| 好看的亚洲午夜视频在线| 免费观看在线综合色| 日本午夜精品| 亚洲精品国产精品粉嫩| 国产精品视频一区二区三区| 国产精品99一区二区三| 欧美精品一区二区久久| 亚洲精品伊人| 精品久久视频| 日产欧产美韩系列久久99| 三级在线观看一区二区| 日韩精品一区二区三区中文字幕| 国产精品天堂蜜av在线播放| 丝袜诱惑一区二区| 国产亚洲精品自拍| 日韩在线网址| 精品三级在线| 在线国产一区二区| 免费人成精品欧美精品| 国产精品片aa在线观看| 日韩中文字幕高清在线观看| 国产精品老牛| 老司机免费视频一区二区三区| 国产成人a视频高清在线观看| 1024精品久久久久久久久| 亚洲狼人精品一区二区三区| 国产精品视频一区视频二区| 精精国产xxxx视频在线野外| 在线观看亚洲精品福利片| 精品国产欧美日韩| 亚洲欧美日本日韩| 精品一区二区三区在线观看视频| 亚洲精华国产欧美| 欧美中文高清| 欧美精品一区二区三区精品| 国产伦精品一区二区三区千人斩 | 国产模特精品视频久久久久| 国产一级成人av| 午夜国产精品视频| 激情久久一区二区| 日韩亚洲精品在线观看| 日韩欧美视频专区| 18国产精品| 黑丝一区二区| 国产精品115| 久久性天堂网| 999久久久免费精品国产| 欧美欧美黄在线二区| 不卡在线一区二区| 久久精品亚洲一区二区| 亚洲伊人精品酒店| 国产99亚洲| 日本一区二区高清不卡| 日韩高清二区| 免费日韩av片| 国产一区欧美| 理论片午夜视频在线观看| 国产视频一区二| 视频一区欧美精品| 久久中文字幕二区| 国产精品多人| 亚洲精品护士| 国产精品女主播一区二区三区| 手机在线电影一区| 青青草伊人久久| 在线视频观看日韩| 不卡福利视频| 精品成人18| 欧美国产不卡| 国产精品久久国产愉拍| 最新亚洲国产| 蜜桃久久久久久久| 亚洲欧美日韩国产综合精品二区| 久久精品国产亚洲夜色av网站| 另类综合日韩欧美亚洲| 国产一区国产二区国产三区| 亚洲精品国产精品粉嫩| 在线观看亚洲精品福利片| 悠悠资源网久久精品| japanese国产精品| 伊人久久成人| 欧美特黄视频| 黄色成人在线网址| 香蕉精品视频在线观看| 亚洲精品一级二级| 色婷婷精品视频| 亚洲成人不卡| 91精品一区国产高清在线gif| 香蕉成人av| 日韩精品影视| 日韩欧美一区免费| 久久久久99| 免费不卡中文字幕在线| 国产精品7m凸凹视频分类| 在线亚洲激情| 日韩三级精品| 国产精品流白浆在线观看| 久久精品色播| 香蕉成人av| 在线一区免费观看| 午夜久久av| 国产精品亲子伦av一区二区三区| 国产精品17p| 精品美女视频 | 欧美日韩91| 国产精品欧美在线观看| 国产一区二区亚洲| 久久久国产亚洲精品| 91成人精品视频| 蜜桃久久av| 国产欧美亚洲一区| 国产黄大片在线观看| 亚洲激情五月| 天堂久久av| 国模大尺度视频一区二区| 精品国产一区二区三区性色av| 国产精品毛片久久| 今天的高清视频免费播放成人| 黄色成人91| 国产精品亚洲一区二区在线观看| 久久久国产精品入口麻豆| 激情视频网站在线播放色| 欧美日韩国产高清| 久久国产免费看| 精品成人18| 免费观看在线综合| 国精品产品一区| 好看的av在线不卡观看| 日韩一区二区三区高清在线观看| 久久久久久久久成人| 欧美三级精品| 丝袜美腿一区二区三区| 国产精品第一| 欧美亚洲国产一区| 欧美在线黄色| 黄色不卡一区| 久久中文字幕一区二区三区| 精品一区欧美| 精品久久网站| 亚洲精品大片| 99精品在线观看| 久久精品99久久久| 久久精品成人| 国产毛片一区二区三区| 婷婷综合五月| 国产精品一二| 亚洲国产日韩欧美在线| 久久久国产精品入口麻豆| 视频一区免费在线观看| 精品资源在线| 日本一不卡视频| 久久中文字幕av| 国产精品红桃| 综合激情网站| 一区在线免费| 青青久久av| 精品国产成人| 国产精品一在线观看| 日韩制服丝袜先锋影音| 欧美成a人免费观看久久| 日韩精彩视频在线观看| 欧美aa国产视频| 波多视频一区| 久久精品一区二区国产| 日韩国产一二三区| 好看不卡的中文字幕| 日韩理论片av| 欧美国产美女| 精品日韩一区| 国产欧美日韩一区二区三区四区| 视频在线在亚洲| 婷婷丁香综合| 久久精品国语| 成人看片网站| 成人在线视频区| 国产欧美自拍| 日本中文字幕一区二区视频| 久久不射网站| 在线观看免费一区二区| 久久精品一区二区不卡| 成人污污视频| 老司机免费视频一区二区三区| 日本视频一区二区| 日韩高清电影一区| 日韩高清电影免费| 日韩av不卡在线观看| 亚洲丝袜美腿一区| 蜜臀av在线播放一区二区三区| 亚洲一区二区网站| 丝袜亚洲精品中文字幕一区| 99热精品在线| 国产亚洲精品v|