Finally I have made my second app in android -paint app- I was so interested in making this app because I like drawing , It’s one of my hobbies.
now let start going into the project.
This is the final result of the project .
Before drawing
After drawing
Change color
Make new page, change the size of the brush ,use eraser change the size of it, save your drawing to the gallery.
Now I will start explaining the coding part
Firstly create new android project, exactly same as previous project.
And create user interface of the app add picture buttons insert background , add dimensions for brush/eraser sizes
<!-- Brush sizes --> <dimen name="small_brush">10dp</dimen> <integer name="small_size">10</integer> <dimen name="medium_brush">20dp</dimen> <integer name="medium_size">20</integer> <dimen name="large_brush">30dp</dimen> <integer name="large_size">30</integer>
,add strings for new page ,brush ,eraser,save, and paint.
<string name="start_new">New</string> <string name="brush">Brush</string> <string name="erase">Erase</string> <string name="save">Save</string> <string name="paint">Paint</string>
inside the activity_main.xml i had made LinearLayout as the main layout.and drag LinearLayout inside th main main layout and to make the rows of the color i have made this for first row
<LinearLayout android:id="@+id/paint_colors" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > </LinearLayout>
and second row
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > </LinearLayout>
the first row has an id because use in java class when the app starts the first default color as selected so that the user can start drawing straight away.i added a new xml file and named it "paint.xml" inside the drawable file and wrote the following code
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item> <shape android:shape="rectangle" > <stroke android:width="4dp" android:color="#FF999999" /> <solid android:color="#00000000" /> <padding android:bottom="0dp" android:left="0dp" android:right="0dp" android:top="0dp" /> </shape> </item> <item> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <stroke android:width="4dp" android:color="#FF999999" /> <solid android:color="#00000000" /> <corners android:radius="10dp" /> </shape> </item> </layer-list>
it is a little complex than it looks at first glance. To create a rounded button appearance, we use two layered Shape drawables, one rectangle outline and theother a rounded stroke.The strokes have gray color , with transparency in the middle through which the background color for each button will be seen(the background color being the color represented by the button).
so, now for each color, i used the following ImageButton structure:
inside the first row LinearLayout
<ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FF660000" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FF660000" /> <ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FFFF0000" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FFFF0000" /> <ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FFFF6600" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FFFF6600" /> <ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FFFFCC00" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FFFFCC00" /> <ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FF009900" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FF009900" /> <ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FF009999" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FF009999" />
inside the second row LinearLayout
<ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FF0000FF" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FF0000FF" /> <ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FF990099" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FF990099" /> <ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FFFF6666" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FFFF6666" /> <ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FFFFFFFF" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FFFFFFFF" /> <ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FF787878" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FF787878" /> <ImageButton android:layout_width="@dimen/large_brush" android:layout_height="@dimen/large_brush" android:layout_margin="2dp" android:background="#FF000000" android:contentDescription="@string/paint" android:onClick="paintClicked" android:src="@drawable/paint" android:tag="#FF000000" />
i used one of the dimension values that i had defined for th color button.
after finishing the user interface i started to implement drawing on the canvas and choosing colors.
create new class named it DrawingView and extends View and then define all the variables that i will use:
//drawing path private Path drawPath; //drawing and canvas paint private Paint drawPaint, canvasPaint; //initial color private int paintColor = 0xFF660000; //canvas private Canvas drawCanvas; //canvas bitmap private Bitmap canvasBitmap;
when the user touches the screen and moves their finger to draw, I used a path to trace their drawing actin on the canvas.Both the canvas and the drawing on top of it are represented by paint objects. The initial paint color corresponds to the first color in the palette i had created before , which will be initiallly selected when the app launches. Finally i declared variables for the canvas and bitmap- the user paths drawn with drawPaint wil be drawn onto the canvas, which is drawn with canvasPaint.
added new method and named it setupDrawing and instantiate some of these variables to set set the class up for drawing .
first instantiate the drawing Path and Paint objects
next set the initial color
and then set the initail path properties:
drawPath = new Path(); drawPaint = new Paint(); //drawPaint.setColor(paintColor); drawPaint.setAntiAlias(true); drawPaint.setStrokeWidth(20); drawPaint.setStyle(Paint.Style.STROKE); drawPaint.setStrokeJoin(Paint.Join.ROUND); drawPaint.setStrokeCap(Paint.Cap.ROUND);
complete the setupDrawing method by instantiating the canvas Paint object:
canvasPaint = new Paint(Paint.DITHER_FLAG);
i set dithering by passing a parameter to constructor.
then override the couple of methods to make the custom view function as a drawing view.
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { //view given size super.onSizeChanged(w, h, oldw, oldh); canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); drawCanvas = new Canvas(canvasBitmap); } @Override protected void onDraw(Canvas canvas) { //draw view canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint); canvas.drawPath(drawPath, drawPaint); }
when the drawing view is on the app screen, we want user touches on it to regester as drawing operations.
to do this we need to listen for touch events.
public boolean onTouchEvent(MotionEvent event) { //detect user touch float touchX = event.getX(); float touchY = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: drawPath.moveTo(touchX, touchY); break; case MotionEvent.ACTION_MOVE: drawPath.lineTo(touchX, touchY); break; case MotionEvent.ACTION_UP: drawCanvas.drawPath(drawPath, drawPaint); drawPath.reset(); break; default: return false; } invalidate(); return true;//Calling invalidate will cause the onDraw method to execute. }
The MotionEvent parameter to the onTouchEvent method will let us respond to particular touch events. the actions we are interesteed in to implement drawing are down,move and up. Added a switch statement in the method to respond .
when the user touches the view, we move to that position to start drawing. when they move thier finger on the View wedraw the path along with their touch. when they lift their finger up off the view , we draw the path and reset it for the next drawing operation.
Let's now talk about implementing the ability for the user to choose colors from the palette.
inside main activity class inside onCreate methode i instantiated variables by retrieving a reference to it from the layout:
drawView = (DrawingView)findViewById(R.id.drawing); LinearLayout paintLayout = (LinearLayout)findViewById(R.id.paint_colors); currPaint = (ImageButton)paintLayout.getChildAt(0); currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed)); smallBrush = getResources().getInteger(R.integer.small_size); mediumBrush = getResources().getInteger(R.integer.medium_size); largeBrush = getResources().getInteger(R.integer.large_size); drawBtn = (ImageButton)findViewById(R.id.draw_btn); drawBtn.setOnClickListener(this); drawView.setBrushSize(mediumBrush); eraseBtn = (ImageButton)findViewById(R.id.erase_btn); eraseBtn.setOnClickListener(this); newBtn = (ImageButton)findViewById(R.id.new_btn); newBtn.setOnClickListener(this); saveBtn = (ImageButton)findViewById(R.id.save_btn); saveBtn.setOnClickListener(this);
get the fir button and store it as the instance varable and use different drawable image on the button to show that it is currently selected:
currPaint = (ImageButton)paintLayout.getChildAt(0); currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
i added this new "paint_pressed.xml" file inside drawable file and wrote the following code
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item> <shape android:shape="rectangle" > <stroke android:width="4dp" android:color="#FF333333" /> <solid android:color="#00000000" /> <padding android:bottom="0dp" android:left="0dp" android:right="0dp" android:top="0dp" /> </shape> </item> <item> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <stroke android:width="4dp" android:color="#FF333333" /> <solid android:color="#00000000" /> <corners android:radius="10dp" /> </shape> </item> </layer-list>
it is very similar to the"paint.xml"drawable we created last time, but with darker color around the paint.
I went go back to main activity class and added paintClicked method
public void paintClicked(View view){ //use chosen color if(view!=currPaint){ //update color ImageButton imgView = (ImageButton)view; String color = view.getTag().toString(); drawView.setColor(color); imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed)); currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint)); currPaint=(ImageButton)view; } }
first check that the user has clicked a paint color that is not the currently selected one,then retrieve the tag we set for each button in the layout , representing the chosen color.
then i needed to use the custom View class to set the color , so i added set color in side Drawing View class
public void setColor(String newColor){ //set color invalidate(); paintColor = Color.parseColor(newColor); drawPaint.setColor(paintColor); }
start by invalidating th View , then set the color for drawing, now going back to the main activity, in paintClicked method after retriving the color tag , call the new method on the custom drawing View object and then update th user interface to reflect the new chosen paint and set the previouse one back to the normal.
now i will discuss the last part of my project. About the ability to erase to create new drawing page ,to save a drawing to the gallary of your device.
in the previouse part i discussed about drawing on the canvas, then now i will discuss how to make the user choose a brush size. The brush size options will appear when the user presses the brush button I added t the interface. To respond to this, extend the opening line of in main activity class declaration to the implement the OnClickListener interface:
public class MainActivity extends Activity implements OnClickListeneroverride onClick method and check for clicks on the drawing button using if statement
@Override public void onClick(View view){ //respond to clicks if(view.getId()==R.id.draw_btn){ //draw button clicked final Dialog brushDialog = new Dialog(this); brushDialog.setTitle("Brush size:"); } }
there are another coditional blocks i will speak about them later.When the user clicks the button i already displayed a dialog presenting them with the three button sizes.Inside the if block, and create a dialog and set the titleThen i defined the dialog layout in "brush_chooser.xml" inside layout file and entering the following code and inside the Layout ,added a button for each size:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <ImageButton android:id="@+id/small_brush" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:contentDescription="@string/sml" android:src="@drawable/small" /> <ImageButton android:id="@+id/medium_brush" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:contentDescription="@string/med" android:src="@drawable/medium" /> <ImageButton android:id="@+id/large_brush" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:contentDescription="@string/lrg" android:src="@drawable/large" /> </LinearLayout>
then dd specified strings to "string.xml" Small ,Medium,Large then add three xml files for each of them
相关推荐
A Second Course in Stochastic Process A Second Course in Stochastic Process
Android in Action, Second Edition is a revision and update of Unlocking Android, pub-lished in April 2009. This book doesn’t fit nicely into the camp of “introductory text,” nor is it a highly ...
2.3 Building an Android application in Eclipse 2.4 The Android Emulator 2.5 Debugging 2.6 Summary Part 2 Exercising the Android SDK 3 User interfaces 3.1 Creating the Activity 3.2 Working with views...
A Second Course in Stochastic Processes
Perfect for kids ages 10 and over who are ready to take a second step after Scratch, Coding Projects in Python teaches kids how to build amazing graphics, fun games, and useful apps. All they need is ...
second DSP firmware app example project provided in CSR ADK 4.0.1
SecondProject:创建虚拟的Secondproject
The growing but still evolving success of the Android platform has ushered in a second mobile technology “gold rush” for app developers. Google Play and Amazon Appstore for Android apps has become ...
App Inventor 2 Building Android Apps takes you step-by-step through the whole process of designing and creating your first two android apps using the free MIT App Inventor 2 software. The book is ...
"Beginning Android Games, Second Edition offers everything you need to join the ranks of successful Android game developers, including Android tablet game app development considerations. You'll start...
Each recipe provides a clear solution and sample code you can use in your project right away. Among numerous topics, this cookbook helps you: Get started with the tooling you need for developing and...
初学者android课本 英文版 及其简单的讲解 但是需要英文功底
Later in the second part the reader will learn RxJava 2.0 step-by-step by starting off with stock data processing and display. Together with this a developer will learn to choose appropriate ...
Thistextisdesignedfortwotypesofstatisticscourses.Theearlychapters,combined with a selection of the case studies, are designed for use in the second half of a two-semester (two-quarter) introductory ...
This practical book describes many asynchronous mechanisms available in the Android Sdk, and provides guidelines for selecting the ones most appropriate for the app you&#8217;re building.Author ...
这里包括两个 eclipse 工程, 在一个工程FirstAndroid里调用另一个工程SecondAndroid里的Activity 和 Service,SecondAndroid只能通过别的app 来启动,它自己不能启动,因为它没有 android.intent.action.MAIN这个...
The first one is an android project,and the second is an intellij plugin project. You can see more information in the respective project,and I hope you can tell me your suggestions. Developed By ...
Sunshine is the companion Android app for the Udacity course Developing Android Apps: Android Fundamentals. Take the course to find out how to build this app a step at a time, and eventually create ...
Spring In Action Second Edition 英文原版 pdf格式 带目录