Android簡單實現(xiàn)畫圖功能
如何在圖片上畫畫呢?這里寫了一個demo,供大家參考
一、先看一眼工程結(jié)構(gòu)
工程結(jié)構(gòu):
二、自定義view
這個自定義view實現(xiàn)了保留軌跡的功能,代碼如下
package picturegame.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import com.winton.picturegame.R; public class GameView extends View{ private Paint paint = null; // private Bitmap originalBitmap = null;//原始圖 private Bitmap new1Bitmap = null; private Bitmap new2Bitmap = null; private float clickX =0; private float clickY=0; private float startX=0; private float startY=0; private boolean isMove = true; private boolean isClear = false; private int color =Color.RED;//默認畫筆顏色為紅色 private float strokeWidth =2.0f;//默認畫筆粗度 public GameView(Context context) { this(context,null); // TODO Auto-generated constructor stub } public GameView(Context context,AttributeSet atts) { this(context,atts,0); // TODO Auto-generated constructor stub } public GameView(Context context,AttributeSet atts,int defStyle) { super(context,atts,defStyle); // TODO Auto-generated constructor stub originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.default_pic).copy(Bitmap.Config.ARGB_8888, true);//加載一張背景 new1Bitmap=originalBitmap.createBitmap(originalBitmap); } //清除函數(shù) public void clear(){ isClear =true; new2Bitmap=originalBitmap.createBitmap(originalBitmap); invalidate();//重載 } public void setStrokeWidth(float width){ this.strokeWidth=width; initPaint(); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); canvas.drawBitmap(writer(new1Bitmap),0,0, null); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub clickX =event.getX(); clickY=event.getY(); if(event.getAction()==MotionEvent.ACTION_DOWN){ isMove =false; invalidate(); return true; } else if(event.getAction()==MotionEvent.ACTION_MOVE){ isMove =true; invalidate(); return true; } return super.onTouchEvent(event); } /** * @Title: writer * @Description: TODO(生成bitmap) * @param @param pic * @param @return 設(shè)定文件 * @return Bitmap 返回類型 * @throws */ public Bitmap writer(Bitmap pic){ initPaint(); Canvas canvas =null; if(isClear){ canvas=new Canvas(new2Bitmap); }else{ canvas=new Canvas(pic); } if(isMove){ canvas.drawLine(startX, startY, clickX, clickY, paint);//劃線 } startX = clickX; startY =clickY; if(isClear){ return new2Bitmap; } return pic; } private void initPaint(){ paint = new Paint();//新建畫筆 paint.setStyle(Style.STROKE);//設(shè)置為畫線 paint.setAntiAlias(true);//可以讓線條圓滑一些 paint.setColor(color);//設(shè)置畫筆顏色 paint.setStrokeWidth(strokeWidth);//設(shè)置畫筆線條的粗細 } /** * @Title: setColor * @Description: TODO(設(shè)置線條顏色的對外接口) * @param @param color 設(shè)定文件 * @return void 返回類型 * @throws */ public void setColor(int color){ this.color=color; initPaint(); } }
三、主頁面布局文件
主頁面布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_horizontal" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" > <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextView android:id="@+id/tv_30" android:layout_width="30dp" android:layout_height="30dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextView android:id="@+id/tv_25" android:layout_width="25dp" android:layout_height="25dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextView android:id="@+id/tv_20" android:layout_width="20dp" android:layout_height="20dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextView android:id="@+id/tv_15" android:layout_width="15dp" android:layout_height="15dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextView android:id="@+id/tv_10" android:layout_width="10dp" android:layout_height="10dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextView android:id="@+id/tv_5" android:layout_width="5dp" android:layout_height="5dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextView android:id="@+id/tv_2" android:layout_width="2dp" android:layout_height="2dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> </LinearLayout> <picturegame.view.GameView android:layout_width="match_parent" android:layout_height="300dp" android:id="@+id/gameview" /> <Button android:layout_width="200dp" android:layout_height="80dp" android:text="clear" android:textColor="@color/black" android:id="@+id/btn_clear" /> </LinearLayout>
四、主Activity代碼
package com.winton.picturegame; import picturegame.view.GameView; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import com.winton.basemodule.BaseActivity; public class MainActivity extends BaseActivity implements OnClickListener { private GameView gameview = null; private Button clear = null; private TextView tv30,tv25,tv20,tv15,tv10,tv5,tv2; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); } @Override public void initView() { // TODO Auto-generated method stub setContentView(R.layout.activity_main); gameview=(GameView)findViewById(R.id.gameview); clear =(Button)findViewById(R.id.btn_clear); tv30=(TextView)findViewById(R.id.tv_30); tv25=(TextView)findViewById(R.id.tv_25); tv20=(TextView)findViewById(R.id.tv_20); tv15=(TextView)findViewById(R.id.tv_15); tv10=(TextView)findViewById(R.id.tv_10); tv5=(TextView)findViewById(R.id.tv_5); tv2=(TextView)findViewById(R.id.tv_2); } @Override public void initListener() { // TODO Auto-generated method stub clear.setOnClickListener(this); tv30.setOnClickListener(this); tv25.setOnClickListener(this); tv20.setOnClickListener(this); tv15.setOnClickListener(this); tv10.setOnClickListener(this); tv5.setOnClickListener(this); tv2.setOnClickListener(this); } @Override public void initData() { // TODO Auto-generated method stub } @Override public void onClick(View v) { // TODO Auto-generated method stub if(v==clear){ gameview.clear(); return; } if(v==tv30){ gameview.setStrokeWidth(30f); return; } if(v==tv25){ gameview.setStrokeWidth(25f); return; } if(v==tv20){ gameview.setStrokeWidth(20f); return; } if(v==tv15){ gameview.setStrokeWidth(15f); return; } if(v==tv10){ gameview.setStrokeWidth(10f); return; } if(v==tv5){ gameview.setStrokeWidth(5f); return; } if(v==tv2){ gameview.setStrokeWidth(2f); return; } } }
五、效果
運行效果圖如下
六、疑問
當(dāng)線條變粗時,線條會出現(xiàn)如上圖中不連續(xù)的問題。請問高手這個怎么處理呢?我猜測應(yīng)該要運行算法,但還不知道怎么運行。
文章就為大家介紹到這,其實還有許多知識點小編也不是很清楚,希望大家可以進行補充擴展,共同進步。
相關(guān)文章
Android中Splash應(yīng)用啟動白屏問題的解決方法
這篇文章主要為大家詳細介紹了Android中Splash應(yīng)用啟動白屏問題的兩種解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02Android應(yīng)用中使用ViewPager和ViewPager指示器來制作Tab標(biāo)簽
這篇文章主要介紹了Android中使用ViewPager和ViewPager指示器來制作Tab標(biāo)簽的方法,ViewPager指示器ViewPageIndicator是一個開源庫,文中舉了一個仿網(wǎng)易新聞客戶端Tab標(biāo)簽的例子,需要的朋友可以參考下2016-03-03Android基于Sqlite實現(xiàn)注冊和登錄功能
這篇文章主要為大家詳細介紹了Android基于Sqlite實現(xiàn)注冊和登錄功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04Android使用GridView實現(xiàn)日歷的簡單功能
這篇文章主要為大家詳細介紹了Android使用GridView實現(xiàn)日歷的簡單功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12android基礎(chǔ)總結(jié)篇之二:Activity的四種launchMode
這篇文章主要介紹了android基礎(chǔ)總結(jié)篇之二:Activity的四種launchMode,有需要的可以了解一下。2016-11-11Android貝塞爾曲線實現(xiàn)填充不規(guī)則圖形并隨手指運動
這篇文章主要為大家詳細介紹了Android貝塞爾曲線實現(xiàn)填充不規(guī)則圖形,并隨手指運動,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-09-09