Por si alguna vez habéis tenido algún problema/duda con definir el tamaño máximo soportado por los EditText o TextView vía código aquí tenéis la solución. Simple pero funcional:
private void editTextMaxLength(EditText ed, int maxLength){
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(maxLength);
ed.setFilters(filterArray);
}
It works!
Roger Sala,
miércoles, 12 de diciembre de 2012
martes, 4 de diciembre de 2012
Google Maps API v2. MapFragment
Por fin!
Los mapas y los Fragments ya se ha unificado. A continuación y sin andarse mucho por las ramas el ejemplo de como añadirlo y como manejar el GoogleMaps.
1.- Necesitamos la API Key que se obtiene de forma distinta a los MapActivity. En el siguiente enlace se detallan los pasos de como obtenerla. Obtener API KEY
2.- Descargar del SDK Manager -> Extras -> Google Play services.
3.- Importar en libs el archivo jar. AndroidSDK -> Extras -> Google -> Google Play Services -> libs -> google-play-services.jar
4.- Ya podemos empezar a generar el código.
AndroidManifest.xml
MainActivity.java
package com.example.maps.fragments;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainActivity extends Activity implements OnClickListener {
private GoogleMap mMap;
private static final LatLng MY_POINT = new LatLng(41.66, 1.54);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Init view elements
((Button) findViewById(R.id.none)).setOnClickListener(this);
((Button) findViewById(R.id.satellite)).setOnClickListener(this);
((Button) findViewById(R.id.hybrid)).setOnClickListener(this);
((Button) findViewById(R.id.normal)).setOnClickListener(this);
((Button) findViewById(R.id.terrain)).setOnClickListener(this);
// Verify Map availability
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the
// map.
if (mMap == null) {
mMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
// addMarkers
addMarkers();
addCameraOption();
}
}
}
private void addMarkers() {
//custom icon
Marker my_marker = mMap.addMarker(new MarkerOptions()
.position(MY_POINT).title("Melbourne")
.snippet("Some informaton: eg: Population: 4,137,400")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
//default icon
// Marker my_marker = mMap.addMarker(new MarkerOptions()
// .position(MY_POINT).title("Catalunya")
// .snippet("Some informaton: eg: Population: 4,137,400"));
}
private void addCameraOption(){
// Move the camera instantly to Sydney with a zoom of 15.
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(MY_POINT, 15));
// Zoom in, animating the camera.
mMap.animateCamera(CameraUpdateFactory.zoomIn());
// Zoom out to zoom level 10, animating with a duration of 2 seconds.
// mMap.animateCamera(CameraUpdateFactory.zoomTo(10), null, 2000);
// Construct a CameraPosition focusing on Mountain View and animate the camera to that position.
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(MY_POINT) // Sets the center of the map to Mountain View
.zoom(17) // Sets the zoom
.bearing(90) // Sets the orientation of the camera to east
.tilt(30) // Sets the tilt of the camera to 30 degrees
.build(); // Creates a CameraPosition from the builder
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.hybrid:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
break;
case R.id.terrain:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
break;
case R.id.none:
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
break;
case R.id.normal:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
break;
case R.id.satellite:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
break;
default:
break;
}
}
}
activity_main.xml
It works!
Roger Sala,
Los mapas y los Fragments ya se ha unificado. A continuación y sin andarse mucho por las ramas el ejemplo de como añadirlo y como manejar el GoogleMaps.
1.- Necesitamos la API Key que se obtiene de forma distinta a los MapActivity. En el siguiente enlace se detallan los pasos de como obtenerla. Obtener API KEY
2.- Descargar del SDK Manager -> Extras -> Google Play services.
3.- Importar en libs el archivo jar. AndroidSDK -> Extras -> Google -> Google Play Services -> libs -> google-play-services.jar
4.- Ya podemos empezar a generar el código.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.maps.fragments"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<permission
android:name="com.example.maps.fragments.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.maps.fragments.permission.MAPS_RECEIVE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.maps.fragments.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>
<!-- API KEY -->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyA-v3ukHyXbPP0db9khnT6pwzNzMfM79Nw" />
</application>
</manifest>
MainActivity.java
package com.example.maps.fragments;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainActivity extends Activity implements OnClickListener {
private GoogleMap mMap;
private static final LatLng MY_POINT = new LatLng(41.66, 1.54);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Init view elements
((Button) findViewById(R.id.none)).setOnClickListener(this);
((Button) findViewById(R.id.satellite)).setOnClickListener(this);
((Button) findViewById(R.id.hybrid)).setOnClickListener(this);
((Button) findViewById(R.id.normal)).setOnClickListener(this);
((Button) findViewById(R.id.terrain)).setOnClickListener(this);
// Verify Map availability
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the
// map.
if (mMap == null) {
mMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
// addMarkers
addMarkers();
addCameraOption();
}
}
}
private void addMarkers() {
//custom icon
Marker my_marker = mMap.addMarker(new MarkerOptions()
.position(MY_POINT).title("Melbourne")
.snippet("Some informaton: eg: Population: 4,137,400")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
//default icon
// Marker my_marker = mMap.addMarker(new MarkerOptions()
// .position(MY_POINT).title("Catalunya")
// .snippet("Some informaton: eg: Population: 4,137,400"));
}
private void addCameraOption(){
// Move the camera instantly to Sydney with a zoom of 15.
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(MY_POINT, 15));
// Zoom in, animating the camera.
mMap.animateCamera(CameraUpdateFactory.zoomIn());
// Zoom out to zoom level 10, animating with a duration of 2 seconds.
// mMap.animateCamera(CameraUpdateFactory.zoomTo(10), null, 2000);
// Construct a CameraPosition focusing on Mountain View and animate the camera to that position.
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(MY_POINT) // Sets the center of the map to Mountain View
.zoom(17) // Sets the zoom
.bearing(90) // Sets the orientation of the camera to east
.tilt(30) // Sets the tilt of the camera to 30 degrees
.build(); // Creates a CameraPosition from the builder
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.hybrid:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
break;
case R.id.terrain:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
break;
case R.id.none:
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
break;
case R.id.normal:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
break;
case R.id.satellite:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
break;
default:
break;
}
}
}
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" >
<!-- <fragment -->
<!-- android:name="com.example.maps.fragments.TopFragment" -->
<!-- android:layout_width="fill_parent" -->
<!-- android:layout_height="100dip" -->
<!-- android:tag="topFragment" /> -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:weightSum="5" >
<Button
android:id="@+id/normal"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Normal"
android:textSize="12sp" />
<Button
android:id="@+id/hybrid"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Hybrid"
android:textSize="12sp" />
<Button
android:id="@+id/satellite"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Satellite"
android:textSize="12sp" />
<Button
android:id="@+id/terrain"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Terrain"
android:textSize="12sp" />
<Button
android:id="@+id/none"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="None"
android:textSize="12sp" />
</LinearLayout>
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>
Aquí tenéis una imagen del MapFragment con el marker personalizado, y con un zoom personalizado de la camera:
It works!
Roger Sala,
miércoles, 21 de noviembre de 2012
Encriptar/Desencriptar datos en 4.2
En algunas ocasiones nos puede interesar encriptar datos para aumentar la seguridad de nuestra aplicación. Para ello podemos usar la siguiente clase que funciona hasta la versión 4.1.2 de Android:
/**
* Util class to perform encryption/decryption over strings.
*/
public final class UtilsEncryption
{
/** The logging TAG */
private static final String TAG = UtilsEncryption.class.getName();
/** */
private static final String KEY = "some_encryption_key";
/**
* Avoid instantiation. <br/>
*/
private UtilsEncryption()
{
}
/** The HEX characters */
private final static String HEX = "0123456789ABCDEF";
/**
* Encrypt a given string. <br/>
*
* @param the string to encrypt
* @return the encrypted string in HEX
*/
public static String encrypt( String cleartext )
{
try
{
byte[] result = process( Cipher.ENCRYPT_MODE, cleartext.getBytes() );
return toHex( result );
}
catch ( Exception e )
{
System.out.println( TAG + ":encrypt:" + e.getMessage() );
}
return null;
}
/**
* Decrypt a HEX encrypted string. <br/>
*
* @param the HEX string to decrypt
* @return the decrypted string
*/
public static String decrypt( String encrypted )
{
try
{
byte[] enc = fromHex( encrypted );
byte[] result = process( Cipher.DECRYPT_MODE, enc );
return new String( result );
}
catch ( Exception e )
{
System.out.println( TAG + ":decrypt:" + e.getMessage() );
}
return null;
}
/**
* Get the raw encryption key. <br/>
*
* @param the seed key
* @return the raw key
* @throws NoSuchAlgorithmException
*/
private static byte[] getRawKey()
throws NoSuchAlgorithmException
{
KeyGenerator kgen = KeyGenerator.getInstance( "AES" );
SecureRandom sr = SecureRandom.getInstance( "SHA1PRNG" );
sr.setSeed( KEY.getBytes() );
kgen.init( 128, sr );
SecretKey skey = kgen.generateKey();
return skey.getEncoded();
}
/**
* Process the given input with the provided mode. <br/>
*
* @param the cipher mode
* @param the value to process
* @return the processed value as byte[]
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
*/
private static byte[] process( int mode, byte[] value )
throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException,
NoSuchPaddingException
{
SecretKeySpec skeySpec = new SecretKeySpec( getRawKey(), "AES" );
Cipher cipher = Cipher.getInstance( "AES" );
cipher.init( mode, skeySpec );
byte[] encrypted = cipher.doFinal( value );
return encrypted;
}
/**
* Decode an HEX encoded string into a byte[]. <br/>
*
* @param the HEX string value
* @return the decoded byte[]
*/
protected static byte[] fromHex( String value )
{
int len = value.length() / 2;
byte[] result = new byte[len];
for ( int i = 0; i < len; i++ )
{
result[i] = Integer.valueOf( value.substring( 2 * i, 2 * i + 2 ), 16 ).byteValue();
}
return result;
}
/**
* Encode a byte[] into an HEX string. <br/>
*
* @param the byte[] value
* @return the HEX encoded string
*/
protected static String toHex( byte[] value )
{
if ( value == null )
{
return "";
}
StringBuffer result = new StringBuffer( 2 * value.length );
for ( int i = 0; i < value.length; i++ )
{
byte b = value[i];
result.append( HEX.charAt( ( b >> 4 ) & 0x0f ) );
result.append( HEX.charAt( b & 0x0f ) );
}
return result.toString();
}
}
Para qué la clase funcione a partir de la 4.2 tenemos que sustituir el siguiente código de la clase anterior:
SecureRandom sr = SecureRandom.getInstance( "SHA1PRNG", "Crypto" );
Este problema es debido a los providers que usa Google en la 4.2. Hasta la 4.1.2 se usa Crypto ya que si hacemos ran.getProvider podemos verlo. A partir de la 4.2 si ejecutamos la misma instrucción nos devuelve AndroidOpenSSL.
Espero que les haya servido.
It works!
Roger Sala,
sábado, 10 de noviembre de 2012
StrictMode
El StrictMode nos permite analizar nuestra aplicación en tiempo de ejecución. Esta disponible a partir de la API 9. Con su uso podemos detectar:
- Escrituras/lecturas en disco.
- Uso de la red
- Violación: log/crash, dropbox, cuadros de diálogos que pueden perjudicar el uso de la aplicación (que sea molesto visitar nuestra app por culpa de los cuadros de dialógos).
A nadie le gusta descargarse una aplicación y tener que esperar 7 segundos para poder realizar una primera acción. A nadie le gusta tener un Progress Dialog y no poder usar la aplicación a su vez. StrictMode, nos ayuda a detectar estos casos y así, podemos mejorar el uso de nuestra aplicación.
Si quieren leer más sobre StrictMode aquí les dejo un post de Android Developers.
A continuación el código a escribir para usar StrictMode:
1.- Con la configuración por defecto:
public void onCreate(Bundle savedInstanceState) {
if (DEVELOPER_MODE) {
StrictMode.enableDefaults();
}
super.onCreate(savedInstanceState);
}
2.- Con la configuración personalizada:
public void onCreate(Bundle savedInstanceState) {
if (DEVELOPER_MODE) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build());
}
super.onCreate(savedInstanceState);
}
IMPORTANTE: Usarlo solo cuando esten debugando o provando la aplicación. Deshabilitarlo para subirla en el Store. Para eso se usa la variable DEVELOPER_MODE.
lunes, 5 de noviembre de 2012
Custom Loading
Si deseamos personalizar los elementos de cargando de nuestra aplicación podemos tan solo tenemos que crear nuestro propio diseño y sobreescribir el de Android. En este post vamos a ver como se realiza dicha acción: El diseño esta hecho a partir de flechas pero cada uno puedo poner lo que desee y el número de elementos que prefiera (aquí solo hay cuatro pero se pueden poner más o menos).
A continuación el código:
res/anim/custom_dialog.xml
LoadingActivity.java
package com.example.blogcustomdialoanimation;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.Menu;
public class LoadingActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loading);
ProgressDialog dialog = new ProgressDialog(this);
dialog.setIndeterminate(true);
dialog.setIndeterminateDrawable(getResources().getDrawable(R.anim.custom_dialog));
dialog.setMessage("Some Text");
dialog.show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_loading, menu);
return true;
}
}
A continuación les dejo las imagenes:
A continuación el código:
res/anim/custom_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@drawable/right"
android:duration="150"/>
<item
android:drawable="@drawable/up"
android:duration="150"/>
<item
android:drawable="@drawable/left"
android:duration="150"/>
<item
android:drawable="@drawable/down"
android:duration="150"/>
</animation-list>
activity_loading.xml
<RelativeLayout 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" >
</RelativeLayout>
LoadingActivity.java
package com.example.blogcustomdialoanimation;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.Menu;
public class LoadingActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loading);
ProgressDialog dialog = new ProgressDialog(this);
dialog.setIndeterminate(true);
dialog.setIndeterminateDrawable(getResources().getDrawable(R.anim.custom_dialog));
dialog.setMessage("Some Text");
dialog.show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_loading, menu);
return true;
}
}
A continuación les dejo las imagenes:
It works!
Roger Sala,
jueves, 1 de noviembre de 2012
ViewFlipper estático y dinámico
Este Widget nos permite cambiar de una vista a otra de forma automática y, si se desea, aplicando animaciones. Por ejemplo:
- Podemos crear un marco de foto digital que cada X segundos vayan cambiando las fotos.
- Podemos añadir nuestra propia publicidad y que vaya cambiando el anuncio cada X segundos.
- Y otros...
En estes post vamos a ver como añadir en nuestro proyecto un ViewFlipper, ya sea con contenido estático, es decir, en el layout definimos el número máximo de elementos que puede tener. O bien, con contenido dinámico, es decir, en nuestra Activity le vamos añadiendo vistas.
Antes de empezar, destacar, que para el uso de un ViewFlipper se recomienda un mínimo de 2 vistas (layout, imageview, textview, etc.). Así pues, aquí les dejo el código:
res/anim/push_in_left.xml
res/anim/push_out_left.xml
activity_flipper.xml
- Podemos crear un marco de foto digital que cada X segundos vayan cambiando las fotos.
- Podemos añadir nuestra propia publicidad y que vaya cambiando el anuncio cada X segundos.
- Y otros...
En estes post vamos a ver como añadir en nuestro proyecto un ViewFlipper, ya sea con contenido estático, es decir, en el layout definimos el número máximo de elementos que puede tener. O bien, con contenido dinámico, es decir, en nuestra Activity le vamos añadiendo vistas.
Antes de empezar, destacar, que para el uso de un ViewFlipper se recomienda un mínimo de 2 vistas (layout, imageview, textview, etc.). Así pues, aquí les dejo el código:
res/anim/push_in_left.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2007 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="700"
android:fromXDelta="100%p"
android:toXDelta="0" />
<alpha
android:duration="700"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
res/anim/push_out_left.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2007 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="700"
android:fromXDelta="0"
android:toXDelta="-100%p" />
<alpha
android:duration="700"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
activity_flipper.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linear_layout_highlighted"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dip"
android:text="Static Flipper with push animation" />
<ViewFlipper
android:id="@+id/flipper_static"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dip"
android:flipInterval="2000" >
<ImageView
android:id="@+id/imageview_highlighted_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="@drawable/android_one" />
<ImageView
android:id="@+id/imageview_highlighted_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:src="@drawable/android_two" />
</ViewFlipper>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dip"
android:text="Dynamic Flipper" />
<ViewFlipper
android:id="@+id/flipper_dynamic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dip"
android:flipInterval="4000" >
</ViewFlipper>
</LinearLayout>
FlipperActivity.java
package com.example.blogviewflipper;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.ViewFlipper;
public class FlipperActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flipper);
// static flipper
ViewFlipper mStaticFlipper = ((ViewFlipper) findViewById(R.id.flipper_static));
mStaticFlipper.startFlipping();
mStaticFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_in_left));
mStaticFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_out_left));
// dynamic flipper
ViewFlipper mDynamicFlipper = ((ViewFlipper) findViewById(R.id.flipper_dynamic));
ImageView image = new ImageView(this);
image.setImageResource(R.drawable.android_one);
image.setScaleType(ScaleType.FIT_CENTER);
mDynamicFlipper.addView(image);
image = new ImageView(this);
image.setImageResource(R.drawable.android_two);
image.setScaleType(ScaleType.FIT_CENTER);
mDynamicFlipper.addView(image);
image = new ImageView(this);
image.setImageResource(R.drawable.android_three);
image.setScaleType(ScaleType.FIT_CENTER);
mDynamicFlipper.addView(image);
mDynamicFlipper.startFlipping();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_flipper, menu);
return true;
}
}
A continuación les dejo una imagen, dónde se muestra el contenido:
It works!
Roger Sala,
Suscribirse a:
Entradas (Atom)