Dec 30, 2014
Dec 8, 2014
Google Play Services 6.5
Google Play services 6.5 includes new features in Google Maps, Google Drive and Google Wallet as well as the recently launched Google Fit API. Also providing developers with more granular control over which Google Play services APIs your app depends on to help you maintain a lean app.
Google Developer content is now available offline
The Google Developer Platform team recently commenced a program to make a subset of the resources available offline to developers who, because of limited or no broadband, had previously been unable to access them. The kits include the latest and greatest content on it such as videos, documentation and SDKs.
Find out more: http://g.co/GDGDevKitPilot
Dec 3, 2014
AdMob Interstitials Best Practices
You can grow your mobile app revenue with high-paying AdMob interstitial ads. Implementing these ads in the right way is better for your users and for you. AdMob poiicies are designed to create a positive user experience, so watch this official video to be sure you're doing it right.
Nov 26, 2014
fplutil - libraries and tools help developing for Android and other platforms
fplutil is a set of small libraries and tools that can be useful when developing applications for Android and other platforms.
Components
Components
- build_all_android is an all-in-one build script that allows you to build, install and run native (C/C++) Android apps from the command line. This is ideal for build automation, but can also be in a developer’s compile/run loop.
- buildutil performs the configuration, build and archive steps of Android and Linux C/C++ applications using a suite of Python modules. This suite of modules can automate builds in a continuous integration environment.
- android_ndk_perf is a desktop tool that enables native (C/C++) developers to measure the CPU utilization of their applications on Android, guiding their optimization efforts.
- libfplutil enables C/C++ developers to write traditional applications (like Hello World) using "main()" and "printf()" on Android.
Nov 24, 2014
Customize Toast to show longer duration
This example show how to customize Toast to show longer duration, by using CountDownTimer to call toast.show() repeatly. And also show how to make the toast counting.
package com.example.androidtoastduration; import android.support.v7.app.ActionBarActivity; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; import android.os.Bundle; import android.os.CountDownTimer; public class MainActivity extends ActionBarActivity { Button text1, text2, text3, text4; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text1 = (Button)findViewById(R.id.text1); text2 = (Button)findViewById(R.id.text2); text3 = (Button)findViewById(R.id.text3); text4 = (Button)findViewById(R.id.text4); text1.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { Toast.makeText( MainActivity.this, "LENGTH_SHORT", Toast.LENGTH_SHORT).show(); }}); text2.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { Toast toast = Toast.makeText( MainActivity.this, "10 second - Not Work!", Toast.LENGTH_SHORT); toast.setDuration(10000); //set duration, not work toast.show(); }}); text3.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { final Toast toast = Toast.makeText( MainActivity.this, "10 second", Toast.LENGTH_SHORT); toast.show(); new CountDownTimer(10000, 1000) { public void onTick(long millisUntilFinished) { toast.show(); } public void onFinish() { toast.cancel(); } }.start(); }}); text4.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { final Toast toast = Toast.makeText( MainActivity.this, "10 second", Toast.LENGTH_SHORT); toast.show(); new CountDownTimer(10000, 1000) { int count = 10; public void onTick(long millisUntilFinished) { toast.show(); count--; toast.setText(count + " sec"); } public void onFinish() { toast.cancel(); } }.start(); }}); } }
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.androidtoastduration.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <Button android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="40dp" android:textStyle="bold" android:text="LENGTH_SHORT" /> <Button android:id="@+id/text2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="40dp" android:textStyle="bold" android:text="10 sec Toast - NOT Work!" /> <Button android:id="@+id/text3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="40dp" android:textStyle="bold" android:text="10 sec Toast" /> <Button android:id="@+id/text4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="40dp" android:textStyle="bold" android:text="10 sec counting Toast" /> </LinearLayout>
Nov 20, 2014
Introduction to Android Auto
Timothy Jordan Introduces Android Auto. Android Auto brings the Android platform to the car in a way that's optimized for the driving experience. It's the same Google platform you already use for phones, tablets, televisions, watches, and more. In fact, all these experiences will often be in the same APK. But now, your app can also extend to the car in a way that's safer and more efficient for the driver. So drivers can stay connected with their hands on the wheel and their eyes on the road.
Using Android Auto is easy. Users go to the Google Play store and download apps that support Android Auto onto their phone.. When they connect their phone to the car, the phone goes into car mode and casts the Android Auto experience to the car's screen. This means that although all the apps and services are actually running on the phone, they're displayed in the car's dash. Users interact with them using the vehicle's controls such as a built-in touchscreen and microphone.
Oct 29, 2014
Android TV - Using the Leanback library
The LeanBack Support Library makes it easy and fast to build great looking Android TV apps. Ankur Kotwal covers the key components to get you started building apps for Android TV using this library.
DevBytes: Android TV - Using the Leanback library
DevBytes: Android TV - Using the Leanback library
Oct 17, 2014
Oct 9, 2014
Google Play services 6.1
Learn about Google Play services 6.1 in this DevByte from Magnus Hyttsten. Google Play services 6.1 adds Enhanced Ecommerce analytics support from Google Tag Manager and offers new improvements to the Google Drive Android API. With this release, we're also including a refresh of the Google Fit developer preview, so that you can test your fitness apps on any Android device.
Google Play services 6.1
Google Play services 6.1
Oct 8, 2014
Html.ImageGetter load image from internet, in AsyncTask
This example code use Html.ImageGetter load image from internet, in AsyncTask, to solve error of android.os.NetworkOnMainThreadException in the old example Html.ImageGetter load image from internet.
In order to load image from internet, permission of "android.permission.INTERNET" have to be added in AndroidManifest.xml.
package com.example.androidhtmltextview; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import android.support.v7.app.ActionBarActivity; import android.text.Html; import android.text.method.LinkMovementMethod; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends ActionBarActivity { public class HttpGetDrawableTask extends AsyncTask<String, Void, Drawable> { TextView taskTextView; String taskHtmlString; HttpGetDrawableTask(TextView v, String s) { taskTextView = v; taskHtmlString = s; } @Override protected Drawable doInBackground(String... params) { Drawable drawable = null; URL sourceURL; try { sourceURL = new URL(params[0]); URLConnection urlConnection = sourceURL.openConnection(); urlConnection.connect(); InputStream inputStream = urlConnection.getInputStream(); BufferedInputStream bufferedInputStream = new BufferedInputStream( inputStream); Bitmap bm = BitmapFactory.decodeStream(bufferedInputStream); // convert Bitmap to Drawable drawable = new BitmapDrawable(getResources(), bm); drawable.setBounds(0, 0, bm.getWidth(), bm.getHeight()); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return drawable; } @Override protected void onPostExecute(Drawable result) { final Drawable taskDrawable = result; if (taskDrawable != null) { taskTextView.setText(Html.fromHtml(taskHtmlString, new Html.ImageGetter() { @Override public Drawable getDrawable(String source) { return taskDrawable; } }, null)); } } } TextView htmlTextViewRemote; String htmlStringRemote = "Image load from internet" + "<img src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_vBn5OxsMM1fUIK0w8awJdKJjgJJ07cBYdWcCscYMujdoEYWWi549p7J5FYnYJSggLjw2pomiwcseExrMX6X8OarAb-bEQwH-sccJtSyHlGnoUrrVtIbgbXP_60n3nzhAwAA1mMuXoNRf/s400/AndroidHtmlTextView_multi_images.png'>"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); htmlTextViewRemote = new TextView(this); setContentView(htmlTextViewRemote); htmlTextViewRemote.setText(Html.fromHtml(htmlStringRemote, new Html.ImageGetter() { @Override public Drawable getDrawable(String source) { Toast.makeText(getApplicationContext(), source, Toast.LENGTH_LONG).show(); HttpGetDrawableTask httpGetDrawableTask = new HttpGetDrawableTask( htmlTextViewRemote, htmlStringRemote); httpGetDrawableTask.execute(source); return null; } }, null)); htmlTextViewRemote.setMovementMethod(LinkMovementMethod.getInstance()); } }
In order to load image from internet, permission of "android.permission.INTERNET" have to be added in AndroidManifest.xml.
Sep 22, 2014
Android graphics performance tips
Animations can be used for good or evil. They can either create rich and compelling experiences that help users understand and use the application, or they can demonstrate just how truly awful the performance of your application is as they stutter and jank all over the screen. "Turn it off! Turn it off!" your users will scream. But there's a better way. Graphics performance is at the heart of smooth and seamless animations: optimize your rendering performance and you can turn your users on instead of having them turn you off.
Chet Haase is the lead of the Android UI Toolkit team, focusing on UI widgets, graphics, performance, animations, and everything else to help make great Android user interfaces. He enjoys taking a break from his real job occasionally to talk about Android at events like this one. His scribblings about Android and less relevant stuff can be found online at google.com/+ChetHaase and @chethaase.
Sep 20, 2014
App Indexing for Google Search
The App Indexing API provides a way for developers to notify Google about deep links in their native apps and allows the Google app, version 3.6 and above, to drive re-engagement through Google Search query autocompletions, providing fast and easy access to inner pages in apps. The deep links reported using the App Indexing API are also used by Google to index app content and are surfaced in Google Search results.
In this video, product manager Lawrence Chang presents an overview of the new App Indexing API for Android that lets you specify links -- through your app itself -- for App Indexing. It also gives you a way to re-engage users through Google Search App autocompletions. We'll provide step-by-step guidelines for how to get started. Take a few minutes and find out how to increase user engagement using the App Indexing API.
Visit: https://developers.google.com/app-indexing/
Sep 12, 2014
Intro To Material Design
These days, UI designers need to be thinking about phones, tablets, laptops, TVs, smartwatches, and beyond. In this DesignByte talk about how Google designers have been working on making cross-platform and multi-screen design easier. We wanted to build a design system that felt at home on every screen, from the smallest watch to the largest TV.
DesignBytes: Intro To Material Design
DesignBytes: Intro To Material Design
Sep 10, 2014
ARM Guide to Unity: Enhancing Your Mobile Games
Unity is the most popular game engine on the planet, used to develop games and applications across multiple platforms by over 50% of all developers. The ARM Guide to Unity shows these developers how to get the most out of Unity when developing under the unique challenges of mobile platforms. It includes:
Download the ARM Guide to Unity, from Mali DEVELOPER CENTER
- Visual quality enhancements for your mobile games and applications
- Optimizations for both CPU and GPU performance
- Battery life extension techniques for applications running on ARM® Cortex® CPU and ARM Mali™ GPU-based devices
Download the ARM Guide to Unity, from Mali DEVELOPER CENTER
Aug 27, 2014
Android example using ScheduledExecutorService
java.util.concurrent.ScheduledExecutorService is an ExecutorService that can schedule commands to run after a given delay, or to execute periodically. This example show how to create a one-shot action using ScheduledExecutorService.
package com.example.androidscheduledexecutorservice; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends ActionBarActivity { Button buttonStart; ScheduledExecutorService scheduledExecutorService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonStart = (Button)findViewById(R.id.start); buttonStart.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "Start", Toast.LENGTH_LONG).show(); scheduledExecutorService = Executors.newScheduledThreadPool(1); scheduledExecutorService.schedule(new Runnable(){ @Override public void run() { MainActivity.this.runOnUiThread(new Runnable(){ @Override public void run() { Toast.makeText(MainActivity.this, "Times-up", Toast.LENGTH_LONG).show(); }}); }}, 5, TimeUnit.SECONDS); } }); } }
<LinearLayout 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:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.androidcountdownprogressbar.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <Button android:id="@+id/start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Start" /> </LinearLayout>
Aug 25, 2014
android.widget.TextClock example
android.widget.TextClock, Added in API level 17, display the current date and/or time as a formatted string.
<LinearLayout 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:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.androidcountdownprogressbar.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <TextClock android:id="@+id/clock" android:layout_width="match_parent" android:layout_height="match_parent" android:textStyle="bold" android:textSize="50sp" /> </LinearLayout>
Aug 23, 2014
Android example to execute threads with ExecutorService
ExecutorService is an Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks. This example implement 5 threads to update ProgressBars in background thread. The threads executed by a ExecutorService, with thread pool of 2. Such that only 2 thread is running at any time.
package com.example.androidcountdownprogressbar; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar; public class MainActivity extends ActionBarActivity { Button buttonStart; ProgressBar progressBar1, progressBar2, progressBar3, progressBar4, progressBar5; CountThread countThread1, countThread2, countThread3, countThread4, countThread5; ExecutorService executorService = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonStart = (Button)findViewById(R.id.start); progressBar1 = (ProgressBar)findViewById(R.id.progressbar1); progressBar2 = (ProgressBar)findViewById(R.id.progressbar2); progressBar3 = (ProgressBar)findViewById(R.id.progressbar3); progressBar4 = (ProgressBar)findViewById(R.id.progressbar4); progressBar5 = (ProgressBar)findViewById(R.id.progressbar5); buttonStart.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { countThread1 = new CountThread(progressBar1); countThread2 = new CountThread(progressBar2); countThread3 = new CountThread(progressBar3); countThread4 = new CountThread(progressBar4); countThread5 = new CountThread(progressBar5); executorService = Executors.newFixedThreadPool(2); executorService.execute(countThread1); executorService.execute(countThread2); executorService.execute(countThread3); executorService.execute(countThread4); executorService.execute(countThread5); }}); } public class CountThread extends Thread{ ProgressBar progressBar; final int MAX_PROGRESS = 10; int progress; CountThread(ProgressBar progressBar){ this.progressBar = progressBar; progress = MAX_PROGRESS; } @Override public void run() { for(int i=0; i<MAX_PROGRESS; i++){ progress--; MainActivity.this.runOnUiThread(new Runnable(){ @Override public void run() { progressBar.setProgress(progress); }}); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
<LinearLayout 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:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.androidcountdownprogressbar.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <ProgressBar android:id="@+id/progressbar1" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="10" android:progress="0" /> <ProgressBar android:id="@+id/progressbar2" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="10" android:progress="0" /> <ProgressBar android:id="@+id/progressbar3" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="10" android:progress="0" /> <ProgressBar android:id="@+id/progressbar4" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="10" android:progress="0" /> <ProgressBar android:id="@+id/progressbar5" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="10" android:progress="0" /> <Button android:id="@+id/start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Start" /> </LinearLayout>
Aug 16, 2014
CountDownTimer and ProgressBar
Example of using CountDownTimer to update ProgressBar.
package com.example.androidcountdownprogressbar; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.os.CountDownTimer; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; public class MainActivity extends ActionBarActivity { Button buttonStart; ProgressBar progressBar; TextView textCounter; MyCountDownTimer myCountDownTimer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonStart = (Button)findViewById(R.id.start); progressBar = (ProgressBar)findViewById(R.id.progressbar); textCounter = (TextView)findViewById(R.id.counter); buttonStart.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { progressBar.setProgress(100); myCountDownTimer = new MyCountDownTimer(10000, 500); myCountDownTimer.start(); }}); } public class MyCountDownTimer extends CountDownTimer { public MyCountDownTimer(long millisInFuture, long countDownInterval) { super(millisInFuture, countDownInterval); } @Override public void onTick(long millisUntilFinished) { textCounter.setText(String.valueOf(millisUntilFinished)); int progress = (int) (millisUntilFinished/100); progressBar.setProgress(progress); } @Override public void onFinish() { textCounter.setText("Finished"); progressBar.setProgress(0); } } }
<LinearLayout 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:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.androidcountdownprogressbar.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <ProgressBar android:id="@+id/progressbar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="100" /> <Button android:id="@+id/start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Start" /> <TextView android:id="@+id/counter" android:layout_width="match_parent" android:layout_height="match_parent" android:textStyle="bold" android:textSize="50sp" android:gravity="center" /> </LinearLayout>
Aug 15, 2014
Android L for game development
Check out what's new for games in the upcoming Android L release. Learn about new features in the OpenGL graphics and OpenSL Audio APIs and get a small taste of the new Google Play Game Services released after Google I/O.
Aug 13, 2014
Mobile Developer's Guide To The Galaxy, 14th Edition
Mobile Developer's Guide To The Galaxy
The free, community driven handbook about mobile technologies: Over 20 experts from all over the world are sharing their know-how on topics like mobile app design, platform-specific aspects of app development, cross-platform development, mobile analytics, accessibility, monetization, app stores, LBS, NFC, app testing and a lot more.
The book is popular among developers wanting to deepen their knowledge and decision-makers planning to enter the mobile business alike. The content gets updates and extended continuously, 13 editions have been published since 2009 and 50,000 hardcopies have been distributed.
The free, community driven handbook about mobile technologies: Over 20 experts from all over the world are sharing their know-how on topics like mobile app design, platform-specific aspects of app development, cross-platform development, mobile analytics, accessibility, monetization, app stores, LBS, NFC, app testing and a lot more.
The book is popular among developers wanting to deepen their knowledge and decision-makers planning to enter the mobile business alike. The content gets updates and extended continuously, 13 editions have been published since 2009 and 50,000 hardcopies have been distributed.
Aug 9, 2014
Samsung Developers Conference Nov 11-13th
Samsung Developers Conference will be hold on Moscone West, San Francisco, November 11-13th, 2014. Signup to be notified: http://samsungdevcon.com/
Aug 7, 2014
Port iOS or Android apps to Windows and Windows Phone
Are you interested in porting your iOS or Android apps to Windows and Windows Phone? Moving to a new platform needn't be as difficult as you think, as this video will demonstrate. Learn about your different options, and the exciting tools available to help you. See you in the Windows app Store!
Check http://channel9.msdn.com/Blogs/One-Dev-Minute/Porting-your-app if you can't view the video here.
Check http://channel9.msdn.com/Blogs/One-Dev-Minute/Porting-your-app if you can't view the video here.
Aug 5, 2014
Display formatted date/time using String.format()
Examples of using String.format() to display formatted calendar:
The layout file is same as last post.
package com.example.androidtime; import java.util.Calendar; import android.support.v7.app.ActionBarActivity; import android.widget.TextView; import android.os.Bundle; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView cal = (TextView)findViewById(R.id.cal); Calendar calendar = Calendar.getInstance(); cal.setText( String.format("%td-%tm-%tY\n", calendar, calendar, calendar) + String.format("%ty/%tm/%td\n", calendar, calendar, calendar) + String.format("%tI:%tM:%tS %tp\n", calendar, calendar, calendar, calendar) + "\n" + String.format("%tD\n", calendar) + String.format("%tc\n", calendar) + String.format("%tF\n", calendar) + String.format("%tr\n", calendar) ); } }
The layout file is same as last post.
Aug 4, 2014
Display date/time in various format with SimpleDateFormat
Examples of using java.text.SimpleDateFormat:
Related: Display formatted date/time using String.format().
package com.example.androidtime; import java.text.SimpleDateFormat; import java.util.Calendar; import android.support.v7.app.ActionBarActivity; import android.widget.TextView; import android.os.Bundle; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView cal = (TextView)findViewById(R.id.cal); Calendar calendar = Calendar.getInstance(); SimpleDateFormat format1 = new SimpleDateFormat("dd-MM-yyyy"); SimpleDateFormat format2 = new SimpleDateFormat("yy/MM/dd"); SimpleDateFormat format3 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); SimpleDateFormat format4 = new SimpleDateFormat("yyyy MMM dd (EEE)"); SimpleDateFormat format5 = new SimpleDateFormat("hh:mm a"); SimpleDateFormat format6 = new SimpleDateFormat("HH:mm"); cal.setText( format1.format(calendar.getTime()) + "\n" + format2.format(calendar.getTime()) + "\n" + format3.format(calendar.getTime()) + "\n" + format4.format(calendar.getTime()) + "\n" + format5.format(calendar.getTime()) + "\n" + format6.format(calendar.getTime()) ); } }
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.androidtime.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <TextView android:id="@+id/cal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:textSize="20sp" /> </LinearLayout>
Related: Display formatted date/time using String.format().
Get time of system
Example to get time (in millisecond and nanosecond) from System, and get instance of Calendar to get current time.
package com.example.androidtime; import java.util.Calendar; import android.support.v7.app.ActionBarActivity; import android.widget.TextView; import android.os.Bundle; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tim = (TextView)findViewById(R.id.tim); TextView cal = (TextView)findViewById(R.id.cal); tim.setText( "currentTimeMillis: " + System.currentTimeMillis() + "\n" + "nanoTime" + System.nanoTime() + "\n" ); Calendar calendar = Calendar.getInstance(); cal.setText( "YEAR: " + calendar.get(Calendar.YEAR) + "\n" + "MONTH: " + calendar.get(Calendar.MONTH) + "\n" + "DAY_OF_MONTH: " + calendar.get(Calendar.DAY_OF_MONTH) + "\n" + "HOUR_OF_DAY: " + calendar.get(Calendar.HOUR_OF_DAY) + "\n" + "MINUTE: " + calendar.get(Calendar.MINUTE) + "\n" + "SECOND: " + calendar.get(Calendar.SECOND) + "\n" ); } }
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.androidtime.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <TextView android:id="@+id/tim" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/cal" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
Jul 29, 2014
Android L Developer Preview - Camera2 API
Ankur Kotwal presents the Camera2 API in Android L, which is designed as a very flexible and unified pipeline for all camera related tasks. This API gives you direct control of the camera subsystem including autofocus, asynchronous burst captures and special effects.
Jul 24, 2014
Building Advanced UIs for Android Wear
How to write apps for Android Wear devices that need to support complex interactions with the user. This video will describe the navigational concepts that Wear apps should support in order to integrate well with the device and provide guidance on designing the UI flow of your app. Will also introduce a new UI widget library that allows app authors to create experiences with the same polish and consistency as the system UI. Using this library, app authors will be able to create "stream-like" UIs that provide the same physics and transition animations as the built-in "home" stream or search results stream.
In detail: This talk is meant to be largely around how to use GridViewPager in order to create "stream-like" experiences in apps for Android Wear.
Building Advanced UIs for Android Wear
In detail: This talk is meant to be largely around how to use GridViewPager in order to create "stream-like" experiences in apps for Android Wear.
Building Advanced UIs for Android Wear
Jul 19, 2014
Jul 15, 2014
Google I/O 2014 Highlights
Relive the best moments of Google I/O 2014, including the keynote, sessions, Developer Sandbox, and After Hours. The keynote and all I/O 2014 sessions are available at: google.com/io
Jul 1, 2014
Google shows L, the latest flavor of Android
At Google I/O in San Francisco, the company previews new design and new user interface features for Android. Dubbed "L", the mobile OS will give users a new look and feel, enhanced notifications, and better performance.
Jun 26, 2014
Official Moto 360 Demo at Google I/O
Meet Moto 360, a classic timepiece powered by Android Wear. Get a sneak peek at just some of the functionalities of Moto 360 in demo we are giving at this year's Google I/O.
Jun 22, 2014
Implement BroadcastReceiver to monitor Bluetooth state changed
Last example show how to Enable Bluetooth using Intent of BluetoothAdapter.ACTION_REQUEST_ENABLE. In this example, we implement a new class BTStateChangedBroadcastReceiver, extends BroadcastReceiver, to monitor Bluetooth state changed.
BTStateChangedBroadcastReceiver.java
Call registerReceiver(...) to register new BTStateChangedBroadcastReceiver(), to the intent of BluetoothAdapter.ACTION_STATE_CHANGED.
activity_main.xml
Permission of "android.permission.BLUETOOTH" is needed in AndroidManifest.xml.
BTStateChangedBroadcastReceiver.java
package com.example.androidbluetooth; import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class BTStateChangedBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); switch(state){ case BluetoothAdapter.STATE_CONNECTED: Toast.makeText(context, "BTStateChangedBroadcastReceiver: STATE_CONNECTED", Toast.LENGTH_SHORT).show(); break; case BluetoothAdapter.STATE_CONNECTING: Toast.makeText(context, "BTStateChangedBroadcastReceiver: STATE_CONNECTING", Toast.LENGTH_SHORT).show(); break; case BluetoothAdapter.STATE_DISCONNECTED: Toast.makeText(context, "BTStateChangedBroadcastReceiver: STATE_DISCONNECTED", Toast.LENGTH_SHORT).show(); break; case BluetoothAdapter.STATE_DISCONNECTING: Toast.makeText(context, "BTStateChangedBroadcastReceiver: STATE_DISCONNECTING", Toast.LENGTH_SHORT).show(); break; case BluetoothAdapter.STATE_OFF: Toast.makeText(context, "BTStateChangedBroadcastReceiver: STATE_OFF", Toast.LENGTH_SHORT).show(); break; case BluetoothAdapter.STATE_ON: Toast.makeText(context, "BTStateChangedBroadcastReceiver: STATE_ON", Toast.LENGTH_SHORT).show(); break; case BluetoothAdapter.STATE_TURNING_OFF: Toast.makeText(context, "BTStateChangedBroadcastReceiver: STATE_TURNING_OFF", Toast.LENGTH_SHORT).show(); break; case BluetoothAdapter.STATE_TURNING_ON: Toast.makeText(context, "BTStateChangedBroadcastReceiver: STATE_TURNING_ON", Toast.LENGTH_SHORT).show(); break; } } }
Call registerReceiver(...) to register new BTStateChangedBroadcastReceiver(), to the intent of BluetoothAdapter.ACTION_STATE_CHANGED.
package com.example.androidbluetooth; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { TextView textInfo; Button buttonEnableBT; BluetoothAdapter bluetoothAdapter; final static int REQUEST_ENABLE_BT = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textInfo = (TextView)findViewById(R.id.info); buttonEnableBT = (Button)findViewById(R.id.enablebt); bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) { textInfo.setText("BlueTooth not supported in this device"); buttonEnableBT.setEnabled(false); }else{ if (bluetoothAdapter.isEnabled()) { buttonEnableBT.setEnabled(false); textInfo.setText("BlueTooth enabled"); }else{ buttonEnableBT.setEnabled(true); textInfo.setText("BlueTooth disabled, click button to turn on BlueTooth."); } //register BroadcastReceiver registerReceiver(new BTStateChangedBroadcastReceiver(), new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); } buttonEnableBT.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }}); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == REQUEST_ENABLE_BT){ if(resultCode==RESULT_OK){ Toast.makeText(MainActivity.this, "BlueTooth Turned On", Toast.LENGTH_LONG).show(); }else{ Toast.makeText(MainActivity.this, "Cancelled", Toast.LENGTH_LONG).show(); } } if (bluetoothAdapter.isEnabled()) { buttonEnableBT.setEnabled(false); textInfo.setText("BlueTooth enabled"); }else{ buttonEnableBT.setEnabled(true); textInfo.setText("BlueTooth disabled, click button to turn on BlueTooth."); } } }
activity_main.xml
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.androidbluetooth.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <TextView android:id="@+id/info" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/enablebt" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Enable BlueTooth" /> </LinearLayout>
Permission of "android.permission.BLUETOOTH" is needed in AndroidManifest.xml.
<uses-permission android:name="android.permission.BLUETOOTH"/>
Jun 18, 2014
Check BlueTooth status, and enable it using Intent of BluetoothAdapter.ACTION_REQUEST_ENABLE
This example check if Bluetooth supported in running device and its ON/OFF status. Then call startActivityForResult() with Intent of BluetoothAdapter.ACTION_REQUEST_ENABLE, when user click button to enable it. Then re-check the status again in onActivityResult() when result returned.
MainActivity.java
activity_main.xml
Add <uses-permission android:name="android.permission.BLUETOOTH"/> in AndroidManifest.xml.
MainActivity.java
package com.example.androidbluetooth; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { TextView textInfo; Button buttonEnableBT; BluetoothAdapter bluetoothAdapter; final static int REQUEST_ENABLE_BT = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textInfo = (TextView)findViewById(R.id.info); buttonEnableBT = (Button)findViewById(R.id.enablebt); bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) { textInfo.setText("BlueTooth not supported in this device"); buttonEnableBT.setEnabled(false); }else{ if (bluetoothAdapter.isEnabled()) { buttonEnableBT.setEnabled(false); textInfo.setText("BlueTooth enabled"); }else{ buttonEnableBT.setEnabled(true); textInfo.setText("BlueTooth disabled, click button to turn on BlueTooth."); } } buttonEnableBT.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }}); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == REQUEST_ENABLE_BT){ if(resultCode==RESULT_OK){ Toast.makeText(MainActivity.this, "BlueTooth Turned On", Toast.LENGTH_LONG).show(); }else{ Toast.makeText(MainActivity.this, "Cancelled", Toast.LENGTH_LONG).show(); } } if (bluetoothAdapter.isEnabled()) { buttonEnableBT.setEnabled(false); textInfo.setText("BlueTooth enabled"); }else{ buttonEnableBT.setEnabled(true); textInfo.setText("BlueTooth disabled, click button to turn on BlueTooth."); } } }
activity_main.xml
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.androidbluetooth.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <TextView android:id="@+id/info" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/enablebt" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Enable BlueTooth" /> </LinearLayout>
Add <uses-permission android:name="android.permission.BLUETOOTH"/> in AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.androidbluetooth" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <uses-permission android:name="android.permission.BLUETOOTH"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.androidbluetooth.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Jun 6, 2014
May 20, 2014
May 19, 2014
Save something in SharedPreferences using SharedPreferences.Editor
If you want to save something (String, setting, value...) in SharedPreferences, such that it can be retrieved later after Activity exited, we can use SharedPreferences.Editor.
Example:
Example:
package com.example.androidsharedpreferences; import android.app.Activity; import android.content.SharedPreferences; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.Spinner; public class MainActivity extends Activity { String[] dayOfWeek = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; EditText editText; Button buttonSave; Spinner spinner; SharedPreferences prefs; final String KEY_SavedText = "Saved Text"; final String KEY_SavedSel = "Saved Selection"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = (EditText)findViewById(R.id.edittext); buttonSave = (Button)findViewById(R.id.save); spinner = (Spinner)findViewById(R.id.spinner); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, dayOfWeek); adapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); //retrieve saved preferences prefs = getPreferences(MODE_PRIVATE); String prefsString = prefs.getString(KEY_SavedText, null); if(prefsString != null){ editText.setText(prefsString); } int prefsInt = prefs.getInt(KEY_SavedSel, -1); if(prefsInt != -1){ spinner.setSelection(prefsInt); } //Save EditText if buttonSave clicked buttonSave.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit(); editor.putString(KEY_SavedText, editText.getText().toString()); editor.commit(); } }); //Save Spinner selection spinner.setOnItemSelectedListener(new OnItemSelectedListener(){ @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit(); editor.putInt(KEY_SavedSel, position); editor.commit(); } @Override public void onNothingSelected(AdapterView<?> parent) {} }); } }
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.androidsharedpreferences.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <EditText android:id="@+id/edittext" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/save" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Save Text" /> <Spinner android:id="@+id/spinner" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
May 14, 2014
Display TextView with multi-color
This example show how to display TextView with multi-color, using Html.fromHtml() and SpannableString.
TextView with multi-color |
package com.example.androidcolortext; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.text.Html; import android.text.SpannableString; import android.text.style.BackgroundColorSpan; import android.text.style.ForegroundColorSpan; import android.widget.TextView; import android.widget.TextView.BufferType; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView colorText1 = (TextView)findViewById(R.id.colortext1); String text1 = "<font COLOR=\'RED\'><b>" + "android-coding" + "</b></font>" + "<font COLOR=\'#00FF00\'><i>" + ".blogspot" + "</i></font>" + ".com"; colorText1.setText(Html.fromHtml(text1)); TextView colorText2 = (TextView)findViewById(R.id.colortext2); SpannableString text2 = new SpannableString("android-coding.blogspot.com"); text2.setSpan(new ForegroundColorSpan(Color.RED), 0, 14, 0); text2.setSpan(new ForegroundColorSpan(Color.GREEN), 6, 11, 0); text2.setSpan(new ForegroundColorSpan(Color.BLUE), 15, text2.length(), 0); colorText2.setText(text2, BufferType.SPANNABLE); TextView colorText3 = (TextView)findViewById(R.id.colortext3); SpannableString text3 = new SpannableString("android-coding.blogspot.com"); text3.setSpan(new BackgroundColorSpan(Color.LTGRAY), 0, text3.length(), 0); text3.setSpan(new ForegroundColorSpan(Color.RED), 0, 14, 0); text3.setSpan(new ForegroundColorSpan(Color.GREEN), 6, 11, 0); text3.setSpan(new ForegroundColorSpan(0xFF0000FF), 14, 23, 0); text3.setSpan(new ForegroundColorSpan(0x500000FF), 23, text3.length(), 0); colorText3.setText(text3, BufferType.SPANNABLE); } }
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.androidcolortext.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <TextView android:id="@+id/colortext1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="50sp" /> <TextView android:id="@+id/colortext2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="50sp" /> <TextView android:id="@+id/colortext3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="50sp" /> </LinearLayout>
May 13, 2014
ComposePathEffect vs SumPathEffect
This example show different effect of ComposePathEffect vs SumPathEffect, on CornerPathEffect and DashPathEffect.
/res/layout/activity_main.xml
MyView.java
MainActivity.java
- More examples of drawing path on custom View.
/res/layout/activity_main.xml
<LinearLayout 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:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.androidview.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="CornerPathEffect radius" /> <SeekBar android:id="@+id/radius" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="500" android:progress="30" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="DashPathEffect phase" /> <SeekBar android:id="@+id/phase" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="30" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ToggleButton android:id="@+id/combineffect" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textOff="SumPathEffect" android:textOn="ComposePathEffect" /> <RadioGroup android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <RadioButton android:id="@+id/styleFill" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="FILL" android:checked="true" /> <RadioButton android:id="@+id/styleStroke" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="STROKE" /> <RadioButton android:id="@+id/styleFillAndStroke" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="FILL_AND_STROKE" /> </RadioGroup> </LinearLayout> <com.example.androidview.MyView android:id="@+id/myview" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
MyView.java
package com.example.androidview; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ComposePathEffect; import android.graphics.CornerPathEffect; import android.graphics.DashPathEffect; import android.graphics.Paint; import android.graphics.Path; import android.graphics.SumPathEffect; import android.graphics.Path.Direction; import android.graphics.PathEffect; import android.util.AttributeSet; import android.view.View; public class MyView extends View { Paint paintBorder, paintCircle; Path pathBorder, pathCircle; Path pathShape; float cornerRadius; float dashPhase; float[] intervals = {50.0f, 50.0f}; //true: ComposePathEffect //false: SumPathEffect boolean combinPathEffect; Paint.Style style = Paint.Style.FILL; public MyView(Context context) { super(context); init(); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { paintBorder = new Paint(); paintBorder.setColor(Color.BLUE); paintBorder.setStrokeWidth(5); paintCircle = new Paint(); paintCircle.setColor(Color.RED); paintCircle.setStrokeWidth(5); pathBorder = new Path(); pathCircle = new Path(); pathShape = new Path(); pathShape.moveTo(0, 0); pathShape.lineTo(10, 20); pathShape.lineTo(20, 0); pathShape.close(); cornerRadius = 30.0f; dashPhase = 30.0f; } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GRAY); pathBorder.reset(); pathBorder.moveTo(50, 50); pathBorder.lineTo(50, getHeight()-50); pathBorder.lineTo(getWidth()-50, getHeight()-50); pathBorder.lineTo(getWidth()-50, 50); pathBorder.close(); float radius; pathCircle.reset(); if(getWidth()>getHeight()){ radius = getHeight()/4; }else{ radius = getWidth()/4; } pathCircle.addCircle(getWidth()/2, getHeight()/2, radius, Direction.CCW); CornerPathEffect cornerPathEffect = new CornerPathEffect(cornerRadius); DashPathEffect dashPathEffect = new DashPathEffect(intervals, dashPhase); PathEffect pathEffect; if(combinPathEffect){ pathEffect = new ComposePathEffect(dashPathEffect, cornerPathEffect); }else{ pathEffect = new SumPathEffect(dashPathEffect, cornerPathEffect); } paintBorder.setStyle(style); paintCircle.setStyle(style); paintBorder.setPathEffect(pathEffect); paintCircle.setPathEffect(pathEffect); canvas.drawPath(pathBorder, paintBorder); canvas.drawPath(pathCircle, paintCircle); } public void setCornerRadius(float r){ cornerRadius = r; invalidate(); } public void setDashPhase(float p){ dashPhase = p; invalidate(); } public void setCombinPathEffect(boolean e){ combinPathEffect = e; invalidate(); } public void setStyle(Paint.Style s){ style = s; invalidate(); } }
MainActivity.java
package com.example.androidview; import android.app.Activity; import android.graphics.Paint; import android.os.Bundle; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.RadioButton; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.ToggleButton; public class MainActivity extends Activity { private MyView myView; private SeekBar seekBarRadius, seekBarPhase; ToggleButton buttonEffect; RadioButton radioFill, radioStroke, radioFillAndStroke; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myView = (MyView)findViewById(R.id.myview); seekBarRadius = (SeekBar)findViewById(R.id.radius); seekBarRadius.setOnSeekBarChangeListener(seekBarRadiusChangeListener); seekBarPhase = (SeekBar)findViewById(R.id.phase); seekBarPhase.setOnSeekBarChangeListener(seekBarPhaseChangeListener); buttonEffect = (ToggleButton)findViewById(R.id.combineffect); buttonEffect.setOnCheckedChangeListener(buttonEffectCheckedChangeListener); radioFill = (RadioButton)findViewById(R.id.styleFill); radioStroke = (RadioButton)findViewById(R.id.styleStroke); radioFillAndStroke = (RadioButton)findViewById(R.id.styleFillAndStroke); radioFill.setOnCheckedChangeListener(radioOnCheckedChangeListener); radioStroke.setOnCheckedChangeListener(radioOnCheckedChangeListener); radioFillAndStroke.setOnCheckedChangeListener(radioOnCheckedChangeListener); } OnSeekBarChangeListener seekBarRadiusChangeListener = new OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { myView.setCornerRadius(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }; OnSeekBarChangeListener seekBarPhaseChangeListener = new OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { myView.setDashPhase(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }; OnCheckedChangeListener buttonEffectCheckedChangeListener = new OnCheckedChangeListener(){ @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { myView.setCombinPathEffect(isChecked); }}; OnCheckedChangeListener radioOnCheckedChangeListener = new OnCheckedChangeListener(){ @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(radioFill.isChecked()){ myView.setStyle(Paint.Style.FILL); }else if(radioStroke.isChecked()){ myView.setStyle(Paint.Style.STROKE); }else{ myView.setStyle(Paint.Style.FILL_AND_STROKE); } } }; }
- More examples of drawing path on custom View.
May 11, 2014
Fill path and stroke with different color
Check the demo video. The outter (deviated) rectangle drawn with Paint with style of Paint.Style.FILL_AND_STROKE, both the filled area and stroke have the same color. The inner (deviated) circle drawn in two times; first time drawn with Paint.Style.FILL to fill the inner area, the second time draw with Paint.Style.STROKE to draw the stroke with different color.
Other files, /res/layout/activity_main.xml and MainActivity.java, refer to last post DiscretePathEffect example.
- More examples of drawing path on custom View.
package com.example.androidview; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.DiscretePathEffect; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Path.Direction; import android.util.AttributeSet; import android.view.View; public class MyView extends View { Paint paintBorder, paintCircle; Path pathBorder, pathCircle; Path pathShape; float segmentLength; float deviation; public MyView(Context context) { super(context); init(); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { paintBorder = new Paint(); paintBorder.setColor(Color.BLUE); paintBorder.setStrokeWidth(20); paintBorder.setStyle(Paint.Style.FILL_AND_STROKE); paintCircle = new Paint(); paintCircle.setStrokeWidth(20); pathBorder = new Path(); pathCircle = new Path(); pathShape = new Path(); pathShape.moveTo(0, 0); pathShape.lineTo(10, 20); pathShape.lineTo(20, 0); pathShape.close(); segmentLength = 30.0f; deviation = 30.0f; } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GRAY); pathBorder.reset(); pathBorder.moveTo(50, 50); pathBorder.lineTo(50, getHeight()-50); pathBorder.lineTo(getWidth()-50, getHeight()-50); pathBorder.lineTo(getWidth()-50, 50); pathBorder.close(); float radius; pathCircle.reset(); if(getWidth()>getHeight()){ radius = getHeight()/4; }else{ radius = getWidth()/4; } pathCircle.addCircle(getWidth()/2, getHeight()/2, radius, Direction.CCW); DiscretePathEffect discretePathEffect = new DiscretePathEffect(segmentLength, deviation); paintBorder.setPathEffect(discretePathEffect); canvas.drawPath(pathBorder, paintBorder); //fill circle with color paintCircle.setColor(Color.RED); paintCircle.setStyle(Paint.Style.FILL); paintCircle.setPathEffect(discretePathEffect); canvas.drawPath(pathCircle, paintCircle); //draw stroke with different color paintCircle.setColor(Color.BLACK); paintCircle.setStyle(Paint.Style.STROKE); paintCircle.setPathEffect(discretePathEffect); canvas.drawPath(pathCircle, paintCircle); } public void setDeviation(int dev){ deviation = (float)dev; invalidate(); } public void setSegmentLength(int seglen){ //force segmentLength not 0 if (seglen==0){ seglen = 1; } segmentLength = (float)seglen; invalidate(); } public void setStrokeWidth(int strwidth){ paintBorder.setStrokeWidth(strwidth); paintCircle.setStrokeWidth(strwidth); invalidate(); } }
Other files, /res/layout/activity_main.xml and MainActivity.java, refer to last post DiscretePathEffect example.
- More examples of drawing path on custom View.
May 10, 2014
DiscretePathEffect example
android.graphics.DiscretePathEffect chop the path into lines of segmentLength, randomly deviating from the original path by deviation.
Main layout, /res/layout/activity_main.xml.
MainActivity.java
MyView.java
- More examples of drawing path on custom View.
Main layout, /res/layout/activity_main.xml.
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.androidview.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="segmentLength"/> <SeekBar android:id="@+id/segmentLength" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="30"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="deviation"/> <SeekBar android:id="@+id/deviation" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="30"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="strokeWidth"/> <SeekBar android:id="@+id/strokeWidth" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="20"/> <com.example.androidview.MyView android:id="@+id/myview" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
MainActivity.java
package com.example.androidview; import android.app.Activity; import android.graphics.PathDashPathEffect; import android.graphics.PathDashPathEffect.Style; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.Spinner; public class MainActivity extends Activity { private MyView myView; private SeekBar seekBarSegmentLength, seekBarDeviation; private SeekBar seekBarStrokeWidth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myView = (MyView)findViewById(R.id.myview); seekBarSegmentLength = (SeekBar)findViewById(R.id.segmentLength); seekBarSegmentLength.setOnSeekBarChangeListener(seekBarSegmentLengthChangeListener); seekBarDeviation = (SeekBar)findViewById(R.id.deviation); seekBarDeviation.setOnSeekBarChangeListener(seekBarDeviationChangeListener); seekBarStrokeWidth = (SeekBar)findViewById(R.id.strokeWidth); seekBarStrokeWidth.setOnSeekBarChangeListener(seekBarStrokeWidthChangeListener); } OnSeekBarChangeListener seekBarSegmentLengthChangeListener = new OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { myView.setSegmentLength(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }; OnSeekBarChangeListener seekBarDeviationChangeListener = new OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { myView.setDeviation(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }; OnSeekBarChangeListener seekBarStrokeWidthChangeListener = new OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { myView.setStrokeWidth(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }; }
MyView.java
package com.example.androidview; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.DiscretePathEffect; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Path.Direction; import android.util.AttributeSet; import android.view.View; public class MyView extends View { Paint paintBorder, paintCircle; Path pathBorder, pathCircle; Path pathShape; float segmentLength; float deviation; public MyView(Context context) { super(context); init(); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { paintBorder = new Paint(); paintBorder.setColor(Color.BLUE); paintBorder.setStrokeWidth(20); paintBorder.setStyle(Paint.Style.STROKE); paintCircle = new Paint(); paintCircle.setColor(Color.RED); paintCircle.setStrokeWidth(20); paintCircle.setStyle(Paint.Style.STROKE); pathBorder = new Path(); pathCircle = new Path(); pathShape = new Path(); pathShape.moveTo(0, 0); pathShape.lineTo(10, 20); pathShape.lineTo(20, 0); pathShape.close(); segmentLength = 30.0f; deviation = 30.0f; } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GRAY); pathBorder.reset(); pathBorder.moveTo(50, 50); pathBorder.lineTo(50, getHeight()-50); pathBorder.lineTo(getWidth()-50, getHeight()-50); pathBorder.lineTo(getWidth()-50, 50); pathBorder.close(); float radius; pathCircle.reset(); if(getWidth()>getHeight()){ radius = getHeight()/4; }else{ radius = getWidth()/4; } pathCircle.addCircle(getWidth()/2, getHeight()/2, radius, Direction.CCW); DiscretePathEffect discretePathEffect = new DiscretePathEffect(segmentLength, deviation); paintBorder.setPathEffect(discretePathEffect); paintCircle.setPathEffect(discretePathEffect); canvas.drawPath(pathBorder, paintBorder); canvas.drawPath(pathCircle, paintCircle); } public void setDeviation(int dev){ deviation = (float)dev; invalidate(); } public void setSegmentLength(int seglen){ //force segmentLength not 0 if (seglen==0){ seglen = 1; } segmentLength = (float)seglen; invalidate(); } public void setStrokeWidth(int strwidth){ paintBorder.setStrokeWidth(strwidth); paintCircle.setStrokeWidth(strwidth); invalidate(); } }
- More examples of drawing path on custom View.
May 9, 2014
Effect of advance, phase, style in PathDashPathEffect
The example make PathDashPathEffect with interactive setting of advance, phase and style; such that you can know how they affect the result.
Main layout, /res/layout/activity_main.xml.
MainActivity.java
MyView.java
- Running PathDashPathEffect example
- More examples of drawing path on custom View.
Main layout, /res/layout/activity_main.xml.
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.androidview.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="advance"/> <SeekBar android:id="@+id/advance" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="30"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="phase"/> <SeekBar android:id="@+id/phase" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="30"/> <Spinner android:id="@+id/style" android:layout_width="match_parent" android:layout_height="wrap_content"/> <com.example.androidview.MyView android:id="@+id/myview" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
MainActivity.java
package com.example.androidview; import android.app.Activity; import android.graphics.PathDashPathEffect; import android.graphics.PathDashPathEffect.Style; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.Spinner; public class MainActivity extends Activity { private MyView myView; private SeekBar seekBarAdvance, seekBarPhase; private Spinner spinnerStyle; private String[] styleNames ={ "PathDashPathEffect.Style.MORPH", "PathDashPathEffect.Style.ROTATE", "PathDashPathEffect.Style.TRANSLATE"}; private Style[] styleSettings = { PathDashPathEffect.Style.MORPH, PathDashPathEffect.Style.ROTATE, PathDashPathEffect.Style.TRANSLATE}; private ArrayAdapter<String> spinnerStyleAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myView = (MyView)findViewById(R.id.myview); seekBarAdvance = (SeekBar)findViewById(R.id.advance); seekBarAdvance.setOnSeekBarChangeListener(seekBarAdvanceChangeListener); seekBarPhase = (SeekBar)findViewById(R.id.phase); seekBarPhase.setOnSeekBarChangeListener(seekBarPhaseChangeListener); spinnerStyle = (Spinner)findViewById(R.id.style); spinnerStyleAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, styleNames); spinnerStyleAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerStyle.setAdapter(spinnerStyleAdapter); spinnerStyle.setOnItemSelectedListener(spinnerStyleOnItemSelectedListener); } OnSeekBarChangeListener seekBarAdvanceChangeListener = new OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { myView.setAdvance(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }; OnSeekBarChangeListener seekBarPhaseChangeListener = new OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { myView.setPhase(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }; OnItemSelectedListener spinnerStyleOnItemSelectedListener = new OnItemSelectedListener(){ @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { myView.setStype(styleSettings[position]); } @Override public void onNothingSelected(AdapterView<?> parent) { // TODO Auto-generated method stub } }; }
MyView.java
package com.example.androidview; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PathDashPathEffect; import android.graphics.Path.Direction; import android.util.AttributeSet; import android.view.View; public class MyView extends View { Paint paint; Path pathBorder, pathCircle; Path pathShape; float phase; float advance; PathDashPathEffect.Style style; public MyView(Context context) { super(context); init(); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { paint = new Paint(); paint.setColor(Color.BLUE); paint.setStrokeWidth(20); paint.setStyle(Paint.Style.STROKE); pathBorder = new Path(); pathCircle = new Path(); pathShape = new Path(); pathShape.moveTo(0, 0); pathShape.lineTo(10, 20); pathShape.lineTo(20, 0); pathShape.close(); phase = 30.0f; advance = 30.0f; style = PathDashPathEffect.Style.MORPH; } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GRAY); pathBorder.reset(); pathBorder.moveTo(50, 50); pathBorder.lineTo(50, getHeight()-50); pathBorder.lineTo(getWidth()-50, getHeight()-50); pathBorder.lineTo(getWidth()-50, 50); pathBorder.close(); float radius; pathCircle.reset(); if(getWidth()>getHeight()){ radius = getHeight()/4; }else{ radius = getWidth()/4; } pathCircle.addCircle(getWidth()/2, getHeight()/2, radius, Direction.CCW); PathDashPathEffect pathDashPathEffect = new PathDashPathEffect(pathShape, advance, phase, style); paint.setPathEffect(pathDashPathEffect); canvas.drawPath(pathCircle, paint); canvas.drawPath(pathBorder, paint); } public void setAdvance(int adv){ advance = (float)adv; invalidate(); } public void setPhase(int ph){ phase = (float)ph; invalidate(); } public void setStype(PathDashPathEffect.Style sty){ style = sty; invalidate(); } }
- Running PathDashPathEffect example
- More examples of drawing path on custom View.
May 8, 2014
Running PathDashPathEffect example
This example implement running PathDashPathEffect, by varying phase parameter.
Modify MyView.java from the post.
- Effect of advance, phase, style in PathDashPathEffect
- More examples of drawing path on custom View
Modify MyView.java from the post.
package com.example.androidview; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Path.Direction; import android.graphics.PathDashPathEffect; import android.util.AttributeSet; import android.view.View; public class MyView extends View { Paint paint; Path path; Path pathShape; float phase; float advance; PathDashPathEffect.Style style; public MyView(Context context) { super(context); init(); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { paint = new Paint(); paint.setColor(Color.RED); paint.setStrokeWidth(20); paint.setStyle(Paint.Style.STROKE); path = new Path(); pathShape = new Path(); pathShape.addCircle(10, 10, 10, Direction.CCW); phase = 0; advance = 30.0f; style = PathDashPathEffect.Style.ROTATE; } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GRAY); path.reset(); path.moveTo(50, 50); path.lineTo(50, getHeight()-50); path.lineTo(getWidth()-50, getHeight()-50); path.lineTo(getWidth()-50, 50); path.close(); phase++; PathDashPathEffect pathDashPathEffect = new PathDashPathEffect(pathShape, advance, phase, style); paint.setPathEffect(pathDashPathEffect); canvas.drawPath(path, paint); invalidate(); } }
- Effect of advance, phase, style in PathDashPathEffect
- More examples of drawing path on custom View
May 7, 2014
PathDashPathEffect example
android.graphics.PathDashPathEffect dash the drawn path by stamping it with the specified shape.
Example:
Modify MyView.java from the post.
Example:
PathDashPathEffect example |
Modify MyView.java from the post.
package com.example.androidview; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Path.Direction; import android.graphics.PathDashPathEffect; import android.util.AttributeSet; import android.view.View; public class MyView extends View { Paint paint; Path path; public MyView(Context context) { super(context); init(); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { paint = new Paint(); paint.setColor(Color.RED); paint.setStrokeWidth(20); paint.setStyle(Paint.Style.STROKE); path = new Path(); Path pathShape = new Path(); pathShape.addCircle(10, 10, 10, Direction.CCW); float advance = 30.0f; float phase = 20.0f; PathDashPathEffect.Style style = PathDashPathEffect.Style.ROTATE; PathDashPathEffect pathDashPathEffect = new PathDashPathEffect(pathShape, advance, phase, style); paint.setPathEffect(pathDashPathEffect); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GRAY); path.reset(); path.moveTo(50, 50); path.lineTo(50, getHeight()-50); path.lineTo(getWidth()-50, getHeight()-50); path.lineTo(getWidth()-50, 50); path.close(); canvas.drawPath(path, paint); } }
Subscribe to:
Posts (Atom)