Android Design in Action: New in Android 4.4
Wednesday, January 15, 2014
Example of ViewAnimator
android.widget.ViewAnimator is a subclass of FrameLayout container that
will perform animations when switching between its views.
<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=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/prev"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="previous" />
<Button
android:id="@+id/next"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="next" />
</LinearLayout>
<ViewAnimator
android:id="@+id/viewanimator"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView 1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 3" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="- Button 4 -" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LinearLayout 4" />
</LinearLayout>
</ViewAnimator>
</LinearLayout>
package com.example.androidviewanimator;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ViewAnimator;
public class MainActivity extends Activity {
Button buttonPrev, buttonNext;
ViewAnimator viewAnimator;
Animation slide_in_left, slide_out_right;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonPrev = (Button)findViewById(R.id.prev);
buttonNext = (Button)findViewById(R.id.next);
viewAnimator = (ViewAnimator)findViewById(R.id.viewanimator);
slide_in_left = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);
slide_out_right = AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right);
viewAnimator.setInAnimation(slide_in_left);
viewAnimator.setOutAnimation(slide_out_right);
buttonPrev.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
viewAnimator.showPrevious();
}});
buttonNext.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
viewAnimator.showNext();
}});
}
}
Example to implement Android TextSwitcher
android.widget.TextSwitcher is a specialized ViewSwitcher that contains
only children of type TextView. A TextSwitcher is useful to animate a
label on screen. Whenever setText(CharSequence) is called, TextSwitcher
animates the current text out and animates the new text in.
Example code to implement TextSwitcher.
Example code to implement TextSwitcher.
package com.example.androidtextswitcher;
import com.example.androidviewanimator.R;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.Typeface;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.TextSwitcher;
import android.widget.TextView;
import android.widget.ViewSwitcher.ViewFactory;
public class MainActivity extends Activity {
Button buttonNext;
TextSwitcher textSwitcher;
Animation slide_in_left, slide_out_right;
String[] TextToSwitched = { "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday" };
int curIndex;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonNext = (Button) findViewById(R.id.next);
textSwitcher = (TextSwitcher) findViewById(R.id.textswitcher);
slide_in_left = AnimationUtils.loadAnimation(this,
android.R.anim.slide_in_left);
slide_out_right = AnimationUtils.loadAnimation(this,
android.R.anim.slide_out_right);
textSwitcher.setInAnimation(slide_in_left);
textSwitcher.setOutAnimation(slide_out_right);
textSwitcher.setFactory(new ViewFactory(){
@Override
public View makeView() {
TextView textView = new TextView(MainActivity.this);
textView.setTextSize(30);
textView.setTextColor(Color.RED);
textView.setGravity(Gravity.CENTER_HORIZONTAL);
textView.setTypeface(Typeface.DEFAULT_BOLD);
textView.setShadowLayer(10, 10, 10, Color.BLACK);
return textView;
}});
curIndex = 0;
textSwitcher.setText(TextToSwitched[curIndex]);
buttonNext.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if(curIndex == TextToSwitched.length-1){
curIndex = 0;
textSwitcher.setText(TextToSwitched[curIndex]);
}else{
textSwitcher.setText(TextToSwitched[++curIndex]);
}
}
});
}
}
<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=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<TextSwitcher
android:id="@+id/textswitcher"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/next"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="next" />
</LinearLayout>
Android example: ImageSwitcher
A simple example to implement ImageSwitcher.
package com.example.androidimageswitcher;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher.ViewFactory;
public class MainActivity extends Activity {
Button buttonNext;
ImageSwitcher imageSwitcher;
Animation slide_in_left, slide_out_right;
int imageResources[] = {
android.R.drawable.ic_dialog_alert,
android.R.drawable.ic_dialog_dialer,
android.R.drawable.ic_dialog_email,
android.R.drawable.ic_dialog_info,
android.R.drawable.ic_dialog_map };
int curIndex;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonNext = (Button) findViewById(R.id.next);
imageSwitcher = (ImageSwitcher) findViewById(R.id.imageswitcher);
slide_in_left = AnimationUtils.loadAnimation(this,
android.R.anim.slide_in_left);
slide_out_right = AnimationUtils.loadAnimation(this,
android.R.anim.slide_out_right);
imageSwitcher.setInAnimation(slide_in_left);
imageSwitcher.setOutAnimation(slide_out_right);
imageSwitcher.setFactory(new ViewFactory() {
@Override
public View makeView() {
ImageView imageView = new ImageView(MainActivity.this);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
LayoutParams params = new ImageSwitcher.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
imageView.setLayoutParams(params);
return imageView;
}
});
curIndex = 0;
imageSwitcher.setImageResource(imageResources[curIndex]);
buttonNext.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (curIndex == imageResources.length - 1) {
curIndex = 0;
imageSwitcher.setImageResource(imageResources[curIndex]);
} else {
imageSwitcher.setImageResource(imageResources[++curIndex]);
}
}
});
}
}
<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=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<ImageSwitcher
android:id="@+id/imageswitcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<Button
android:id="@+id/next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="next" />
</LinearLayout>
Good official lessons teach Caching Bitmaps and Managing Bitmap Memory
When your app have to load a number of bitmap, memory allocation will
get complicated. Here is official lessons from developer.android.com.
- Caching Bitmaps teach you using a memory and disk bitmap cache to improve the responsiveness and fluidity of your UI when loading multiple bitmaps.
- Managing Bitmap Memory teach specific things you can do to facilitate garbage collection and bitmap reuse.
Example of ViewFlipper
android.widget.ViewFlipper is a simple ViewAnimator that will
animate between two or more views that have been added to it. Only one
child is shown at a time. If requested, can automatically flip between
each child at a regular interval.
<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=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/prev"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="previous" />
<Button
android:id="@+id/next"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="next" />
</LinearLayout>
<ViewFlipper
android:id="@+id/viewflipper"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="- Button 2 -" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LinearLayout 2" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter something" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LinearLayout 3" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ViewFlipper is a simple ViewAnimator that
will animate between two or more views that
have been added to it. Only one child is shown
at a time. If requested, can automatically
flip between each child at a regular interval." />
</ViewFlipper>
</LinearLayout>
package com.example.androidviewflipper;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ViewFlipper;
public class MainActivity extends Activity {
Button buttonPrev, buttonNext;
ViewFlipper viewFlipper;
Animation slide_in_left, slide_out_right;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonPrev = (Button) findViewById(R.id.prev);
buttonNext = (Button) findViewById(R.id.next);
viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);
slide_in_left = AnimationUtils.loadAnimation(this,
android.R.anim.slide_in_left);
slide_out_right = AnimationUtils.loadAnimation(this,
android.R.anim.slide_out_right);
viewFlipper.setInAnimation(slide_in_left);
viewFlipper.setOutAnimation(slide_out_right);
buttonPrev.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
viewFlipper.showPrevious();
}
});
buttonNext.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
viewFlipper.showNext();
}
});
;
}
}
Bi-direction sliding ViewFlipper
Last exercise show a Example of ViewFlipper.
It always slide from left to right, no matter you click previous or
next button. In this exercise, we will implement bi-direction sliding.
Slide to right if you click next button, slide left if you click
previous button. This technique can also be applied on ViewAnimator, TextSwitcher, ImageSwitcher and ViewSwitcher.
Create /res/anim/ folder, and create the following XMLs to define the animation.
slide_in_left.xml:
slide_in_right.xml:
slide_out_left.xml:
slide_out_right.xml:
Modify layout file, all child View of <ViewFlipper> have android:layout_width="match_parent".
Main code;
Create /res/anim/ folder, and create the following XMLs to define the animation.
slide_in_left.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-50%p" android:toXDelta="0"
android:duration="1000"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="1000" />
</set>
slide_in_right.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="50%p" android:toXDelta="0"
android:duration="1000"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="1000" />
</set>
slide_out_left.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-50%p"
android:duration="1000"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="1000" />
</set>
slide_out_right.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="50%p"
android:duration="1000"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="1000" />
</set>
Modify layout file, all child View of <ViewFlipper> have android:layout_width="match_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: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=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/prev"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="previous" />
<Button
android:id="@+id/next"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="next" />
</LinearLayout>
<ViewFlipper
android:id="@+id/viewflipper"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="- Button 2 -" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LinearLayout 2" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter something" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="LinearLayout 3" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ViewFlipper is a simple ViewAnimator that
will animate between two or more views that
have been added to it. Only one child is shown
at a time. If requested, can automatically
flip between each child at a regular interval." />
</ViewFlipper>
</LinearLayout>
Main code;
package com.example.androidviewflipper;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ViewFlipper;
public class MainActivity extends Activity {
Button buttonPrev, buttonNext;
ViewFlipper viewFlipper;
Animation slide_in_left, slide_out_right;
Animation slide_in_right, slide_out_left;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonPrev = (Button) findViewById(R.id.prev);
buttonNext = (Button) findViewById(R.id.next);
viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);
slide_in_left = AnimationUtils.loadAnimation(this,
R.anim.slide_in_left);
slide_out_right = AnimationUtils.loadAnimation(this,
R.anim.slide_out_right);
slide_in_right = AnimationUtils.loadAnimation(this,
R.anim.slide_in_right);
slide_out_left = AnimationUtils.loadAnimation(this,
R.anim.slide_out_left);
//viewFlipper.setInAnimation(slide_in_left);
//viewFlipper.setOutAnimation(slide_out_right);
buttonPrev.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
viewFlipper.setInAnimation(slide_in_right);
viewFlipper.setOutAnimation(slide_out_left);
viewFlipper.showPrevious();
}
});
buttonNext.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
viewFlipper.setInAnimation(slide_in_left);
viewFlipper.setOutAnimation(slide_out_right);
viewFlipper.showNext();
}
});
;
}
}
How to build Open JavaFX for Android
Here (https://blogs.oracle.com/jfxprg/entry/how_to_build_open_javafx) is a short recipe for baking JavaFX for Android dalvik. Just a few ingredients needed but each one requires special care
Android Programming: Pushing the Limits
Unleash the power of the Android OS and build the kinds of brilliant, innovative apps users love to use
If you already know your way around the Android OS and can build a
simple Android app in under an hour, this book is for you. If you’re
itching to see just how far you can push it and discover what Android is
really capable of, it’s for you. And if you’re ready to learn how to
build advanced, intuitive, innovative apps that are a blast to use, this
book is definitely for you.
From custom views and advanced multi-touch gestures, to integrating
online web services and exploiting the latest geofencing and activity
recognition features, ace Android developer, Erik Hellman, delivers
expert tips, tricks and little-known techniques for pushing the Android
envelope so you can:
- Optimize your components for the smoothest user experience possible
- Create your own custom Views
- Push the boundaries of the Android SDK
- Master Android Studio and Gradle
- Make optimal use of the Android audio, video and graphics APIs
- Program in Text-To-Speech and Speech Recognition
- Make the most of the new Android maps and location API
- Use Android connectivity technologies to communicate with remote devices
- Perform background processing
- Use Android cryptography APIs
- Find and safely use hidden Android APIs
- Cloud-enable your applications with Google Play Services
- Distribute and sell your applications on Google Play Store
Learn how to unleash the power of Android and transform your apps from good to great in Android Programming: Pushing the Limits.
Java Programming for Android Developers For Dummies
Get started creating Android apps with Java in no time!
The demand for Android apps is not slowing down but many mobile
developers who want to create Android apps lack the necessary Java
background. This beginner guide gets you up and running with using Java
to create Android apps with no prior knowledge or experienced necessary!
- Shows you the basic Java development concepts and techniques that are necessary to develop Android apps
- Explores what goes into creating an Android app to give you a better understanding of the various elements
- Addresses how to deal with standard programming challenges and debugging
Beginning Android Programming with Java For Dummies puts you well on your way toward creating Android apps quickly with Java.
Download The Windows Getting Started Guide
This guide will point you to the right developer tools, tutorials, and
resources. Jump in. The next generation is what you make it.
Download here.
and more resources on Microsoft Student web site.
Download here.
and more resources on Microsoft Student web site.
Using GestureDetector to detect user swipe, onFling()
Previous exercise demonstrate "Bi-direction sliding ViewFlipper"
controlled by buttons. This exercise show how to implements
GestureDetector.OnGestureListener to detect user swipe to update
ViewFlipper.
Keep using the layout and animation XML files in last exercise.
package com.example.androidviewflipper;
import android.os.Bundle;
import android.app.Activity;
import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.Toast;
import android.widget.ViewFlipper;
public class MainActivity extends Activity implements
GestureDetector.OnGestureListener {
private GestureDetectorCompat mDetector;
Button buttonPrev, buttonNext;
ViewFlipper viewFlipper;
Animation slide_in_left, slide_out_right;
Animation slide_in_right, slide_out_left;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDetector = new GestureDetectorCompat(this,this);
buttonPrev = (Button) findViewById(R.id.prev);
buttonNext = (Button) findViewById(R.id.next);
viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);
slide_in_left = AnimationUtils.loadAnimation(this,
R.anim.slide_in_left);
slide_out_right = AnimationUtils.loadAnimation(this,
R.anim.slide_out_right);
slide_in_right = AnimationUtils.loadAnimation(this,
R.anim.slide_in_right);
slide_out_left = AnimationUtils.loadAnimation(this,
R.anim.slide_out_left);
//viewFlipper.setInAnimation(slide_in_left);
//viewFlipper.setOutAnimation(slide_out_right);
buttonPrev.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
viewFlipper.setInAnimation(slide_in_right);
viewFlipper.setOutAnimation(slide_out_left);
viewFlipper.showPrevious();
}
});
buttonNext.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
viewFlipper.setInAnimation(slide_in_left);
viewFlipper.setOutAnimation(slide_out_right);
viewFlipper.showNext();
}
});
;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
this.mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
@Override
public boolean onDown(MotionEvent arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
float sensitvity = 50;
if((e1.getX() - e2.getX()) > sensitvity){
viewFlipper.setInAnimation(slide_in_right);
viewFlipper.setOutAnimation(slide_out_left);
viewFlipper.showPrevious();
Toast.makeText(MainActivity.this,
"Previous", Toast.LENGTH_SHORT).show();
}else if((e2.getX() - e1.getX()) > sensitvity){
viewFlipper.setInAnimation(slide_in_left);
viewFlipper.setOutAnimation(slide_out_right);
viewFlipper.showNext();
Toast.makeText(MainActivity.this,
"Next", Toast.LENGTH_SHORT).show();
}
return true;
}
@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
}
Keep using the layout and animation XML files in last exercise.
Detect Gesture by implementing GestureDetector.SimpleOnGestureListener
This example show how to detect user gesture by implementing
GestureDetector.SimpleOnGestureListener. It have the same result as last
exercise of "GestureDetector".
GestureDetector.SimpleOnGestureListener provides an implementation for all of the on<TouchEvent> methods by returning false for all of them. Thus we can override only the methods we care about. In our application, we have to detect onFling() only. So we can extend GestureDetector.SimpleOnGestureListener instead of implementing the GestureDetector.OnGestureListener interface.
MainActivity.java
Keep using the layout and animation XML files in the exercise of "Bi-direction sliding ViewFlipper".
GestureDetector.SimpleOnGestureListener provides an implementation for all of the on<TouchEvent> methods by returning false for all of them. Thus we can override only the methods we care about. In our application, we have to detect onFling() only. So we can extend GestureDetector.SimpleOnGestureListener instead of implementing the GestureDetector.OnGestureListener interface.
MainActivity.java
package com.example.androidviewflipper;
import android.os.Bundle;
import android.app.Activity;
import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.Toast;
import android.widget.ViewFlipper;
public class MainActivity extends Activity{
private GestureDetectorCompat mDetector;
Button buttonPrev, buttonNext;
ViewFlipper viewFlipper;
Animation slide_in_left, slide_out_right;
Animation slide_in_right, slide_out_left;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDetector = new GestureDetectorCompat(this, new MyGestureListener());
buttonPrev = (Button) findViewById(R.id.prev);
buttonNext = (Button) findViewById(R.id.next);
viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);
slide_in_left = AnimationUtils.loadAnimation(this,
R.anim.slide_in_left);
slide_out_right = AnimationUtils.loadAnimation(this,
R.anim.slide_out_right);
slide_in_right = AnimationUtils.loadAnimation(this,
R.anim.slide_in_right);
slide_out_left = AnimationUtils.loadAnimation(this,
R.anim.slide_out_left);
buttonPrev.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
viewFlipper.setInAnimation(slide_in_right);
viewFlipper.setOutAnimation(slide_out_left);
viewFlipper.showPrevious();
}
});
buttonNext.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
viewFlipper.setInAnimation(slide_in_left);
viewFlipper.setOutAnimation(slide_out_right);
viewFlipper.showNext();
}
});
;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
this.mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
float sensitvity = 50;
if((e1.getX() - e2.getX()) > sensitvity){
viewFlipper.setInAnimation(slide_in_right);
viewFlipper.setOutAnimation(slide_out_left);
viewFlipper.showPrevious();
Toast.makeText(MainActivity.this,
"Previous", Toast.LENGTH_SHORT).show();
}else if((e2.getX() - e1.getX()) > sensitvity){
viewFlipper.setInAnimation(slide_in_left);
viewFlipper.setOutAnimation(slide_out_right);
viewFlipper.showNext();
Toast.makeText(MainActivity.this,
"Next", Toast.LENGTH_SHORT).show();
}
return true;
}
}
}
Keep using the layout and animation XML files in the exercise of "Bi-direction sliding ViewFlipper".
ActionBarCompat with ShareActionProvider
This exercise implement MenuItem of Share action in ActionBarCompat, and
ShareActionProvider to share text if user click on the Share on the
Share item. Base on last exercise "Handle onOptionsItemSelected() for ActionBarCompat".
Modify /res/menu/main.xml to add new item of action_share.
MainActivity.java.
ActionBarCompat with Share ShareActionProvider |
Modify /res/menu/main.xml to add new item of action_share.
<menu
xmlns:myapp="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_share"
android:title="Share"
myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"
myapp:showAsAction="always|withText" />
<item
android:id="@+id/action_settings"
myapp:showAsAction="always|withText"
android:title="@string/action_settings"/>
</menu>
MainActivity.java.
package com.example.testactionbarcompat;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.ShareActionProvider;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
private ShareActionProvider myShareActionProvider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
//add MenuItem(s) to ActionBar using Java code
MenuItem menuItem_Info = menu.add(0, R.id.menuid_info, 0, "Info");
menuItem_Info.setIcon(android.R.drawable.ic_menu_info_details);
MenuItemCompat.setShowAsAction(menuItem_Info,
MenuItem.SHOW_AS_ACTION_ALWAYS|MenuItem.SHOW_AS_ACTION_WITH_TEXT);
//Handle share menu item
MenuItem shareItem = menu.findItem(R.id.action_share);
myShareActionProvider = (ShareActionProvider)
MenuItemCompat.getActionProvider(shareItem);
setShareIntent();
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
//return super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.action_settings:
//match with /res/menu/main.xml
Toast.makeText(this, "Setting", Toast.LENGTH_SHORT).show();
return true;
case R.id.menuid_info:
//match with defined in onCreateOptionsMenu()
Toast.makeText(this, "Info", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
//Set the share intent
private void setShareIntent(){
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("plain/text");
intent.putExtra(Intent.EXTRA_TEXT, "Hello from android-er.blogspot.com");
myShareActionProvider.setShareIntent(intent);
}
}
ActionBarCompat with ShareActionProvider to update dynamic content
Last exercise "ActionBarCompat with ShareActionProvider"
setup share content in onCreateOptionsMenu(). The share data will not
be updated after then. In this exercise, ShareIntent will be updated
when user update content.
In my experiment, onOptionsItemSelected() will not be called when Share menu item clicked. So a TextWatcher is implemented when any EditText changed, to update ShareIntent.
Modify layout to add EditTexts for user to enter email address, title and content.
/res/menu/main.xml, same as before.
MainActivity.java
In my experiment, onOptionsItemSelected() will not be called when Share menu item clicked. So a TextWatcher is implemented when any EditText changed, to update ShareIntent.
ActionBarCompat with ShareActionProvider to update dynamic content |
<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=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<EditText
android:id="@+id/fieldemailaddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="email address" />
<EditText
android:id="@+id/fieldemailtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello from android-er.blogspot.com"
android:hint="email title"/>
<EditText
android:id="@+id/fieldemailcontent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="email content"/>
</LinearLayout>
/res/menu/main.xml, same as before.
<menu
xmlns:myapp="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_share"
android:title="Share"
myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"
myapp:showAsAction="always|withText" />
<item
android:id="@+id/action_settings"
myapp:showAsAction="always|withText"
android:title="@string/action_settings"/>
</menu>
MainActivity.java
package com.example.testactionbarcompat;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.ShareActionProvider;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
EditText fieldEmailAddress, fieldEmailTitle, fieldEmailContent;
private ShareActionProvider myShareActionProvider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fieldEmailAddress = (EditText)findViewById(R.id.fieldemailaddress);
fieldEmailTitle = (EditText)findViewById(R.id.fieldemailtitle);
fieldEmailContent = (EditText)findViewById(R.id.fieldemailcontent);
fieldEmailAddress.addTextChangedListener(myTextWatcher);
fieldEmailTitle.addTextChangedListener(myTextWatcher);
fieldEmailContent.addTextChangedListener(myTextWatcher);
}
/*
* update ActionProvider by calling setShareIntent()
* When any EditText changed
*/
TextWatcher myTextWatcher = new TextWatcher(){
@Override
public void afterTextChanged(Editable s) {
setShareIntent();
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {}
};
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
//add MenuItem(s) to ActionBar using Java code
MenuItem menuItem_Info = menu.add(0, R.id.menuid_info, 0, "Info");
menuItem_Info.setIcon(android.R.drawable.ic_menu_info_details);
MenuItemCompat.setShowAsAction(menuItem_Info,
MenuItem.SHOW_AS_ACTION_ALWAYS|MenuItem.SHOW_AS_ACTION_WITH_TEXT);
//Handle share menu item
MenuItem shareItem = menu.findItem(R.id.action_share);
myShareActionProvider = (ShareActionProvider)
MenuItemCompat.getActionProvider(shareItem);
setShareIntent();
//return true;
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
//return super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.action_share:
//It never called in my experiment
Toast.makeText(this, "Share", Toast.LENGTH_SHORT).show();
setShareIntent();
return false;
case R.id.action_settings:
//match with /res/menu/main.xml
Toast.makeText(this, "Setting", Toast.LENGTH_SHORT).show();
return true;
case R.id.menuid_info:
//match with defined in onCreateOptionsMenu()
Toast.makeText(this, "Info", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
//Set the share intent
private void setShareIntent(){
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("plain/text");
intent.putExtra(Intent.EXTRA_EMAIL,
new String[]{fieldEmailAddress.getText().toString()});
intent.putExtra(Intent.EXTRA_SUBJECT,
fieldEmailTitle.getText().toString());
intent.putExtra(Intent.EXTRA_TEXT,
fieldEmailContent.getText().toString());
myShareActionProvider.setShareIntent(intent);
}
}
Install the new Google Mobile Ads SDK for Android
Google have made some big changes recently to the SDK for Android; it's now included as part of Google Play services 4.0.
If you're an Android developer you'll be familiar with Google Play services, a unified platform which makes it easy to integrate Google features into your Android apps, delivered through the Play Store and updated at regular intervals. Now that AdMob is part of the package, a key benefit is that changes to the Google Mobile Ads SDK for Android get pushed seamlessly to users through Google Play services. For most SDK updates you don’t need to update your apps each time it changes, saving you development time. Follow these instructions to install the SDK.
If you're an Android developer you'll be familiar with Google Play services, a unified platform which makes it easy to integrate Google features into your Android apps, delivered through the Play Store and updated at regular intervals. Now that AdMob is part of the package, a key benefit is that changes to the Google Mobile Ads SDK for Android get pushed seamlessly to users through Google Play services. For most SDK updates you don’t need to update your apps each time it changes, saving you development time. Follow these instructions to install the SDK.
Implement Socket on Android to communicate with Raspberry Pi
There is a post "Java exercise - Implement client and server to communicate using Socket" in my another blog, Hello Raspberry Pi.
In which, both host (implement ServerSocket and Socket) and client
(implement Socket) are run on Raspberry Pi to setup communication
between application via socket. Actually both the host and client can
run on any PC with Java.
The client side in the post is ported to Android in this exercise, setup Socket in AsyncTask, to communicate with Raspberry Pi. The updated version of Host (run socket operation in background thread) run on Raspberry Pi or any other PC is here.
MainActivity.java
Layout
AndroidManifest.xml have to be modified to add <uses-permission android:name="android.permission.INTERNET"/>
The client side in the post is ported to Android in this exercise, setup Socket in AsyncTask, to communicate with Raspberry Pi. The updated version of Host (run socket operation in background thread) run on Raspberry Pi or any other PC is here.
Implement Socket on Android |
package com.example.androidclient;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView textResponse;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = (EditText)findViewById(R.id.address);
editTextPort = (EditText)findViewById(R.id.port);
buttonConnect = (Button)findViewById(R.id.connect);
buttonClear = (Button)findViewById(R.id.clear);
textResponse = (TextView)findViewById(R.id.response);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonClear.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
textResponse.setText("");
}});
}
OnClickListener buttonConnectOnClickListener =
new OnClickListener(){
@Override
public void onClick(View arg0) {
/*
* You have to verify editTextAddress and
* editTextPort are input as correct format.
*/
MyClientTask myClientTask = new MyClientTask(
editTextAddress.getText().toString(),
Integer.parseInt(editTextPort.getText().toString()));
myClientTask.execute();
}};
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response;
MyClientTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
@Override
protected Void doInBackground(Void... arg0) {
try {
Socket socket = new Socket(dstAddress, dstPort);
InputStream inputStream = socket.getInputStream();
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
}
socket.close();
response = byteArrayOutputStream.toString("UTF-8");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}
}
Layout
<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=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<EditText
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="dstAddress" />
<EditText
android:id="@+id/port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="dstPort" />
<Button
android:id="@+id/connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connect..."/>
<Button
android:id="@+id/clear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Clear"/>
<TextView
android:id="@+id/response"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
AndroidManifest.xml have to be modified to add <uses-permission android:name="android.permission.INTERNET"/>
Learning Mobile App Development: A Hands-on Guide to Building Apps with iOS and Android
Learning Mobile App Development: A Hands-on Guide to Building Apps with iOS and Android
- The Only Tutorial Covering BOTH iOS and Android—for students and professionals alike!
Now, one book can help you master mobile app development with both
market-leading platforms: Apple’s iOS and Google’s Android. Perfect for
both students and professionals, Learning Mobile App Development is the
only tutorial with complete parallel coverage of both iOS and Android.
With this guide, you can master either platform, or both—and gain a
deeper understanding of the issues associated with developing mobile
apps.
You’ll develop an actual working app on both iOS and Android, mastering
the entire mobile app development lifecycle, from planning through
licensing and distribution.
Each tutorial in this book has been carefully designed to support
readers with widely varying backgrounds and has been extensively tested
in live developer training courses. If you’re new to iOS, you’ll also
find an easy, practical introduction to Objective-C, Apple’s native
language.
All source code for this book, organized by chapter, is available at https://github.com/LearningMobile/BookApps
Coverage includes
- Understanding the unique design challenges associated with mobile apps
- Setting up your Android and iOS development environments
- Mastering Eclipse development tools for Android and Xcode 5 tools for iOS
- Designing interfaces and navigation schemes that leverage each platform’s power
- Reliably integrating persistent data into your apps
- Using lists (Android) or tables (iOS) to effectively present data to users
- Capturing device location, displaying it, and using it in your apps
- Accessing hardware devices and sensors
- Publishing custom apps internally within an organization
- Monetizing your apps on Apple’s AppStore or the Google Play marketplace, as well as other ways of profiting from app development, such as consulting and developer jobs
Creating Dynamic UI with Android Fragments
Creating Dynamic UI with Android Fragments
Leverage the power of Android fragments to develop dynamic user interfaces for your apps
Overview
- Learn everything you need to know to provide dynamic multi-screen UIs within a single activity
- Integrate the rich UI features demanded by today’s mobile users
- Understand the basics of using fragments and how to use them to create more adaptive and dynamic user experiences
In Detail
To create a dynamic and multi-pane user interface on Android, you need
to encapsulate UI components and activity behaviors into modules that
you can swap into and out of your activities. You can create these
modules with the fragment class, which behaves somewhat like a nested
activity that can define its own layout and manage its own lifecycle.
When a fragment specifies its own layout, it can be configured in
different combinations with other fragments inside an activity to modify
your layout configuration for different screen sizes (a small screen
might show one fragment at a time, but a large screen can show two or
more).
Creating Dynamic UI with Android Fragments shows you how to create
modern Android applications that meet the high expectations of today’s
users. You will learn how to incorporate rich navigation features like
swipe-based screen browsing and how to create adaptive UIs that ensure
your application looks fantastic whether run on a low cost smartphone or
the latest tablet.
This book looks at the impact fragments have on Android UI design and
their role in both simplifying many common UI challenges and providing
new ways to incorporate rich UI behaviors.
You will learn how to use fragments to create UIs that automatically
adapt to device differences. We look closely at the roll of fragment
transactions and how to work with the Android back stack. Leveraging
this understanding, we then explore several specialized fragment-related
classes like ListFragment and DialogFragment as well as rich navigation
features like swipe-based screen browsing.
What you will learn from this book
- Understand the role and capabilities of fragments
- Explore the fragment-oriented features of Android Studio
- Create an app UI that works effectively on smartphones and tablets
- Use fragments to create engaging navigation capabilities like swipe-based screen browsing
- Work with special purpose fragment classes like ListFragment and DialogFragment
- Dynamically manage fragments using the FragmentTransaction class
- Learn appropriate application design for communicating between fragments
- Efficiently handle fragment creation and lifecycle
- Simplify cross-thread UI handling with fragments
- Form multi-screen UIs that run within a single activity
Approach
A fast-paced tutorial that guides you through everything you need to know about dynamic UI design for Android devices.
Who this book is written for
This book is for developers with a basic understanding of Android
programming who would like to improve the appearance and usability of
their applications. Whether you’re looking to create a more interactive
user experience, create more dynamically adaptive UIs, provide better
support for tablets and smartphones in a single app, reduce the
complexity of managing your app UIs, or you are just trying to expand
your UI design philosophy, then this book is for you.
Android Security Cookbook
Android Security Cookbook
Practical recipes to delve into Android's security mechanisms by
troubleshooting common vulnerabilities in applications and Android OS
versions
Overview
- Analyze the security of Android applications and devices, and exploit common vulnerabilities in applications and Android operating systems
- Develop custom vulnerability assessment tools using the Drozer Android Security Assessment Framework
- Reverse-engineer Android applications for security vulnerabilities
- Protect your Android application with up to date hardening techniques
In Detail
Android Security Cookbook discusses many common vulnerabilities and
security related shortcomings in Android applications and operating
systems. The book breaks down and enumerates the processes used to
exploit and remediate these vulnerabilities in the form of detailed
recipes and walkthroughs.
The book also teaches readers to use an Android Security Assessment
Framework called Drozer and how to develop plugins to customize the
framework.
Other topics covered include how to reverse-engineer Android
applications to find common vulnerabilities, and how to find common
memory corruption vulnerabilities on ARM devices. In terms of
application protection this book will show various hardening techniques
to protect application components, the data stored, secure networking.
In summary, Android Security Cookbook provides a practical analysis into
many areas of Android application and operating system security and
gives the
What you will learn from this book
- Set up the Android development tools and frameworks
- Engage in Application security concepts
- Use the Drozer Android Security Assessment Framework
- Customize and develop your own plugins for the Drozer Framework
- Exploit, enumerate, and analyze common application level exploits
- Protect applications from common vulnerabilities and exploits
- Reverse-engineer applications for common code level vulnerabilities
- Secure application networking, SSL/TLS
- Encryption to protect application data
Approach
"Android Security Cookbook' breaks down and enumerates the processes
used to exploit and remediate Android app security vulnerabilities in
the form of detailed recipes and walkthroughs.
Who this book is written for
"Android Security Cookbook" is aimed at anyone who is curious about
Android app security and wants to be able to take the necessary
practical measures to protect themselves; this means that Android
application developers, security researchers and analysts, penetration
testers, and generally any CIO, CTO, or IT managers facing the impeding
onslaught of mobile devices in the business environment will benefit
from reading this book.
VelocityTracker, track the velocity of touch events
It's a example of using Android's VelocityTracker. It's a helper for
tracking the velocity of touch events, for implementing flinging and
other such gestures. Use obtain() to retrieve a new instance of the
class when you are going to begin tracking. Put the motion events you
receive into it with addMovement(MotionEvent). When you want to
determine the velocity call computeCurrentVelocity(int) and then call
getXVelocity(int) and getYVelocity(int) to retrieve the velocity for
each pointer id.
Example of using Android's VelocityTracker |
package com.example.androidvelocitytracker;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity {
TextView textAvtion, textVelocityX, textVelocityY,
textMaxVelocityX, textMaxVelocityY;
VelocityTracker velocityTracker = null;
float maxXVelocity;
float maxYVelocity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textAvtion = (TextView) findViewById(R.id.action);
textVelocityX = (TextView) findViewById(R.id.velocityx);
textVelocityY = (TextView) findViewById(R.id.velocityy);
textMaxVelocityX = (TextView) findViewById(R.id.maxvelocityx);
textMaxVelocityY = (TextView) findViewById(R.id.maxvelocityy);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain();
} else {
velocityTracker.clear();
}
velocityTracker.addMovement(event);
maxXVelocity = 0;
maxYVelocity = 0;
textVelocityX.setText("X-velocity (pixel/s): 0");
textVelocityY.setText("Y-velocity (pixel/s): 0");
textMaxVelocityX.setText("max. X-velocity: 0");
textMaxVelocityY.setText("max. Y-velocity: 0");
break;
case MotionEvent.ACTION_MOVE:
velocityTracker.addMovement(event);
velocityTracker.computeCurrentVelocity(1000);
//1000 provides pixels per second
float xVelocity = velocityTracker.getXVelocity();
float yVelocity = velocityTracker.getYVelocity();
if(xVelocity > maxXVelocity){
//max in right side
maxXVelocity = xVelocity;
}
if(yVelocity > maxYVelocity){
//Max in down side
maxYVelocity = yVelocity;
}
textVelocityX.setText("X-velocity (pixel/s): " + xVelocity);
textVelocityY.setText("Y-velocity (pixel/s): " + yVelocity);
textMaxVelocityX.setText("max. X-velocity: " + maxXVelocity);
textMaxVelocityY.setText("max. Y-velocity: " + maxYVelocity);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
velocityTracker.recycle();
break;
}
return true;
}
}
<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=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<TextView
android:id="@+id/action"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/velocityx"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/maxvelocityx"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/velocityy"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/maxvelocityy"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Get the Android version of device
The static final int Build.VERSION.SDK_INT store user-visible SDK version of the framework; its possible values are defined in Build.VERSION_CODES.
This exercise use Android's SparseArrays to store SDK_INT-Build.VERSION_CODES pairs. SparseArrays map integers to Objects. Unlike a normal array of Objects, there can be gaps in the indices. It is intended to be more memory efficient than using a HashMap to map Integers to Objects, both because it avoids auto-boxing keys and its data structure doesn't rely on an extra entry object for each mapping.
This exercise use Android's SparseArrays to store SDK_INT-Build.VERSION_CODES pairs. SparseArrays map integers to Objects. Unlike a normal array of Objects, there can be gaps in the indices. It is intended to be more memory efficient than using a HashMap to map Integers to Objects, both because it avoids auto-boxing keys and its data structure doesn't rely on an extra entry object for each mapping.
Get the Android version of device |
package com.example.androidversion;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.util.SparseArray;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity {
static SparseArray<String> arrayVC = new SparseArray<String>();
static {
arrayVC.append(VERSION_CODES.BASE, "The original, first, version of Android.");
arrayVC.append(VERSION_CODES.BASE_1_1, "First Android update, officially called 1.1");
arrayVC.append(VERSION_CODES.CUPCAKE, "Android 1.5");
arrayVC.append(VERSION_CODES.CUR_DEVELOPMENT, "Magic version number...");
arrayVC.append(VERSION_CODES.DONUT, "Android 1.6");
arrayVC.append(VERSION_CODES.ECLAIR, "Android 2.0");
arrayVC.append(VERSION_CODES.ECLAIR_0_1, "Android 2.0.1");
arrayVC.append(VERSION_CODES.ECLAIR_MR1, "Android 2.1");
arrayVC.append(VERSION_CODES.FROYO, "Android 2.2");
arrayVC.append(VERSION_CODES.GINGERBREAD,"Android 2.3");
arrayVC.append(VERSION_CODES.GINGERBREAD_MR1, "Android 2.3.3");
arrayVC.append(VERSION_CODES.HONEYCOMB, "Android 3.0");
arrayVC.append(VERSION_CODES.HONEYCOMB_MR1, "Android 3.1");
arrayVC.append(VERSION_CODES.HONEYCOMB_MR2, "Android 3.2");
arrayVC.append(VERSION_CODES.ICE_CREAM_SANDWICH,"Android 4.0");
arrayVC.append(VERSION_CODES.ICE_CREAM_SANDWICH_MR1,"Android 4.0.3");
arrayVC.append(VERSION_CODES.JELLY_BEAN, "Android 4.1");
arrayVC.append(VERSION_CODES.JELLY_BEAN_MR1, "Android 4.2");
arrayVC.append(VERSION_CODES.JELLY_BEAN_MR2, "Android 4.3");
arrayVC.append(VERSION_CODES.KITKAT, "Android 4.4");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
TextView textView = new TextView(this);
setContentView(textView);
int version = Build.VERSION.SDK_INT;
String BuildVersion = arrayVC.get(version, "unknown");
textView.setText(BuildVersion);
}
}
VelocityTracker and VelocityTrackerCompat
The post "VelocityTracker, track the velocity of touch events"
for one touch point tracking using VelocityTracker. Together
with android.support.v4.view.VelocityTrackerCompat (Helper for accessing
features in VelocityTracker introduced after API level 4 in a backwards
compatible fashion), we can track velocity for multi-touch tracking on
post-HONEYCOMB device.
package com.example.androidvelocitytracker;
import android.os.Build;
import android.os.Bundle;
import android.os.Build.VERSION_CODES;
import android.support.v4.view.VelocityTrackerCompat;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity {
TextView textAvtion, textVelocityX0, textVelocityY0,
textVelocityX1, textVelocityY1;
TextView textVersion;
VelocityTracker velocityTracker = null;
static SparseArray<String> arrayVC = new SparseArray<String>();
static {
arrayVC.append(VERSION_CODES.BASE, "The original, first, version of Android.");
arrayVC.append(VERSION_CODES.BASE_1_1, "First Android update, officially called 1.1");
arrayVC.append(VERSION_CODES.CUPCAKE, "Android 1.5");
arrayVC.append(VERSION_CODES.CUR_DEVELOPMENT, "Magic version number...");
arrayVC.append(VERSION_CODES.DONUT, "Android 1.6");
arrayVC.append(VERSION_CODES.ECLAIR, "Android 2.0");
arrayVC.append(VERSION_CODES.ECLAIR_0_1, "Android 2.0.1");
arrayVC.append(VERSION_CODES.ECLAIR_MR1, "Android 2.1");
arrayVC.append(VERSION_CODES.FROYO, "Android 2.2");
arrayVC.append(VERSION_CODES.GINGERBREAD,"Android 2.3");
arrayVC.append(VERSION_CODES.GINGERBREAD_MR1, "Android 2.3.3");
arrayVC.append(VERSION_CODES.HONEYCOMB, "Android 3.0");
arrayVC.append(VERSION_CODES.HONEYCOMB_MR1, "Android 3.1");
arrayVC.append(VERSION_CODES.HONEYCOMB_MR2, "Android 3.2");
arrayVC.append(VERSION_CODES.ICE_CREAM_SANDWICH,"Android 4.0");
arrayVC.append(VERSION_CODES.ICE_CREAM_SANDWICH_MR1,"Android 4.0.3");
arrayVC.append(VERSION_CODES.JELLY_BEAN, "Android 4.1");
arrayVC.append(VERSION_CODES.JELLY_BEAN_MR1, "Android 4.2");
arrayVC.append(VERSION_CODES.JELLY_BEAN_MR2, "Android 4.3");
arrayVC.append(VERSION_CODES.KITKAT, "Android 4.4");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textAvtion = (TextView) findViewById(R.id.action);
textVelocityX0 = (TextView) findViewById(R.id.velocityx0);
textVelocityY0 = (TextView) findViewById(R.id.velocityy0);
textVelocityX1 = (TextView) findViewById(R.id.velocityx1);
textVelocityY1 = (TextView) findViewById(R.id.velocityy1);
textVersion = (TextView)findViewById(R.id.version);
int version = Build.VERSION.SDK_INT;
String BuildVersion = arrayVC.get(version, "unknown");
textVersion.setText(BuildVersion);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
int index = event.getActionIndex();
int pointerId = event.getPointerId(index);
switch (action) {
case MotionEvent.ACTION_DOWN:
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain();
} else {
velocityTracker.clear();
}
velocityTracker.addMovement(event);
if(pointerId == 0){
textVelocityX0.setText("X-velocity (pixel/s): 0");
textVelocityY0.setText("Y-velocity (pixel/s): 0");
}else if(pointerId == 1){
textVelocityX1.setText("X-velocity (pixel/s): 0");
textVelocityY1.setText("Y-velocity (pixel/s): 0");
}
break;
case MotionEvent.ACTION_MOVE:
velocityTracker.addMovement(event);
velocityTracker.computeCurrentVelocity(1000);
//1000 provides pixels per second
float xVelocity = VelocityTrackerCompat.getXVelocity(
velocityTracker, pointerId);
float yVelocity = VelocityTrackerCompat.getYVelocity(
velocityTracker, pointerId);
if(pointerId == 0){
textVelocityX0.setText("X-velocity (pixel/s): " + xVelocity);
textVelocityY0.setText("Y-velocity (pixel/s): " + yVelocity);
}else if(pointerId == 1){
textVelocityX1.setText("X-velocity (pixel/s): " + xVelocity);
textVelocityY1.setText("Y-velocity (pixel/s): " + yVelocity);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
velocityTracker.recycle();
break;
}
return true;
}
}
<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=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<TextView
android:id="@+id/version"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/action"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:text="pointer 0"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/velocityx0"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/velocityy0"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:text="pointer 1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/velocityx1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/velocityy1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Subscribe to:
Posts (Atom)