2012-05-06 14 views
5

Me gustaría poner algo de nuevo a este sitio MUY útil, así que esto no es realmente una pregunta, sino más bien mi solución a este problema. También me gustaría añadir que esta solución fue obtenida a partir del soporte de este sitio y muchos otros, por lo que representa los esfuerzos combinados de muchos otros desarrolladores. ¡A ellos les digo gracias!Control de página de Android como control de página de iPhone

La PREGUNTA es "¿Cómo se puede recrear los aspectos horizontales de scrollView de las aplicaciones de iPhone y el control de página asociado en el entorno de Android?"

Esto surgió porque quería mostrar los pasos en la receta, el método asociado para cada paso y los ingredientes necesarios en una sola vista de desplazamiento. También quería un control de página para mostrar al usuario dónde estaban en los pasos y permitirles pasar a cualquier paso específico

Esta parte de mi aplicación muestra los pasos en una receta. Cada paso aparece en una página y tiene tres componentes. Un identificador de paso (es decir, PASO 1, PASO 2), un método y los ingredientes necesarios para el paso.

Debajo de la sección de recetas, mostramos un control de página que muestra qué página está activa y se puede usar para navegar a páginas específicas. Notará que el control de página tiene botones de imagen y las dos imágenes son círculos simples, uno para la página no seleccionada (page.png) y otra para la página seleccionada (page_selected.png)

Cuando se crea la actividad, los pasos para la receta seleccionada se recuperan de los datos y la sección de desplazamiento creada al agregar una vista para cada paso en la receta. Al deslizar la barra de desplazamiento de la vista se ajusta a la página siguiente o anterior y en la pantalla del localizador se actualiza para indicar qué página está en

3 primeros diseños de XML (res/layout)

recipe.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:orientation="vertical" > 

<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" > 

<!--Scroller section--> 

    <HorizontalScrollView 
     android:id="@+id/scroll_view" 
     android:layout_width="match_parent" 
     android:layout_height="320dp" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:layout_marginTop="100dp" > 

      <LinearLayout 
       android:id="@+id/methodScrollView" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:orientation="horizontal" > 
      </LinearLayout> 

    </HorizontalScrollView> 

<!-- pager section --> 

    <LinearLayout 
     android:id="@+id/pager" 
     android:layout_width="match_parent" 
     android:layout_height="20dp" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentTop="true" 
     android:layout_marginLeft="20dp" 
     android:layout_marginRight="20dp" 
     android:layout_marginTop="430dp" 
     android:gravity="center" 
     android:orientation="horizontal" > 

    </LinearLayout> 

</RelativeLayout> 

recipesscroll.xml (la vista que se añadirá a la sección scroller para cada paso de la receta. tenga en cuenta que la sección scroller tiene una onTouchlistner en recipeViewController.java para manejar página desplazamiento)

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/recipeScroll" 
    android:layout_width="320dp" 
    android:layout_height="320dp" 
    android:gravity="center_vertical" > 

    <TextView 
    android:id="@+id/method" 
    style="@style/scrollMethod" 
    android:layout_width="wrap_content" 
    android:layout_height="200dp" 
    android:layout_alignParentTop="true" 
    android:text="Method" /> 

    <TextView 
    android:id="@+id/ingredients" 
    style="@style/scrollIngredients" 
    android:layout_width="wrap_content" 
    android:layout_height="120dp" 
    android:layout_alignParentTop="true" 
    android:text="Ingredients" /> 

    <TextView 
    android:id="@+id/methodStep" 
    style="@style/scrollStep" 
    android:layout_width="wrap_content" 
    android:layout_height="20dp" 
    android:layout_alignParentTop="true" 
    android:text="Step" /> 

</RelativeLayout> 

recipiespager.xml (la vista que se agregará a la sección del buscapersonas para cada paso de la receta. Tenga en cuenta que cada uno de éstos tendrá un evento de clic en recipeViewController.java que desplazarse a la página específica seleccionada en el control de buscapersonas)

<?xml version="1.0" encoding="utf-8"?> 
<Button xmlns:android="http://schemas.android.com/apk/res/android" 
      style="@style/pageButton" 
      android:layout_marginLeft="10dp" 
      android:layout_width="16dp" 
      android:layout_height="16dp" 
      android:onClick="selectPage"> 

</Button> 

Esto es todo reunido en recipeViewController.java

//my package name change this to yours 
package com.infactdata.spinAdinner; 

import java.util.ArrayList; 

//DataModel is the model for my data change this to yours or ignore 
because it is just away of holding the data that will populate the views 
import com.infactdata.plist.DataModel; 

import android.content.res.Resources; 
import android.graphics.Typeface; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.View.OnTouchListener; 
import android.widget.Button; 
import android.widget.HorizontalScrollView; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.RelativeLayout; 
import android.widget.TableLayout; 
import android.widget.TableRow; 
import android.widget.TextView; 

public class RecipeViewController extends RootViewController { 
    private DataModel currentData; 
    HorizontalScrollView h_scroll; 
    int numberOfPages = 0; 
    int thePage; 
    int otherPage; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     //first of the xml files 
     setContentView(R.layout.recipe); 

     //reference to my global variables 
     GlobalClass global = (GlobalClass)getApplicationContext(); 

     //because I wanted a particular type face 
     Typeface face=Typeface.createFromAsset(getAssets(), "fonts/trebucit.ttf"); 

     //VERY IMPORTANT because we need to use this to add the content to the scroll 
     and pager sections 
     LayoutInflater inflater = getLayoutInflater(); 

     //current data held a dataModel 
     currentData = global.getCurrent(); 

     currentName.setText(currentData.getName()); 

     String imageFile = currentData.getImage(); 
     Resources r = getResources(); 

     int res = r.getIdentifier(imageFile, "drawable", "com.infactdata.spinAdinner"); 
     image.setImageResource(res); 

     //recources that change the pager indicators to different images 
     thePage = r.getIdentifier("page_selected", "drawable","com.infactdata.spinAdinner"); 
     otherPage = r.getIdentifier("page", "drawable", "com.infactdata.spinAdinner"); 

     //Get the method(ArrayList) out of the currentData(DataModel). This is the array of 
     data that will fill the added view with different content (ie. the specific 
     instructions for the recipe step. This could be your own data array. 

     ArrayList<String[]> method = new ArrayList<String[]>(); 
     method = currentData.getMethod(0); 
     numberOfPages = method.size(); 

     //now to build the views by adding the content and then adding the text for that 
     content that reflects the instructions for the step in the recipe 

     for(int i = 0; i < method.size(); i++){ 

      String[] methodStep = method.get(i); 

      //find the scroll view 
      LinearLayout scroll = (LinearLayout) findViewById(R.id.methodScrollView); 

      //find the recipe scroller. the second xml file 
      RelativeLayout step = (RelativeLayout)findViewById(R.id.recipeScroll); 

      //add the recipe step (step) to the scrollview (scroll) 
      step = (RelativeLayout)inflater.inflate(R.layout.recipescroll, scroll, false); 

      //add the instructions for this step in the recipe 
      TextView stage = (TextView)step.findViewById(R.id.methodStep); 
      stage.setText(methodStep[0].toString()); 
      stage.setTypeface(face); 

      TextView methodText = (TextView)step.findViewById(R.id.method); 
      methodText.setText(methodStep[1].toString()); 
      methodText.setTypeface(face); 

      TextView ingredients = (TextView)step.findViewById(R.id.ingredients); 
      ingredients.setText(methodStep[2].toString()); 
      ingredients.setTypeface(face); 

      //create method step and add to scroll 
      scroll.addView(step); 

      //pager setup is a duplicate of the above 
      //find the pager 
      LinearLayout pager = (LinearLayout) findViewById(R.id.pager); 

      //find the pager button. the third xml file 
      Button page = (Button)inflater.inflate(R.layout.recipespager, pager, false); 

      //give each button it own ID. This will be used to test which button should be highlighted and used to move to a specific page. This is because the ID is equal to the page number (0 based of course) 
      page.setId(i); 

      //because this is a fresh construction we will be on page 0 so highlight that button 
      if (i == 0){ 
       page.setBackgroundResource(thePage); 
      } 

      //create page control and add to pager 
      pager.addView(page); 
     } 

     //create the onTouch controls 

     h_scroll = (HorizontalScrollView) findViewById(R.id.scroll_view); 
     h_scroll.setOnTouchListener(scrolling); 

} 

private OnTouchListener scrolling = new OnTouchListener(){ 
    public boolean onTouch(View v, MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == 
     MotionEvent.ACTION_CANCEL){ 
      int scrollX = h_scroll.getScrollX(); 
      int itemWidth = h_scroll.getMeasuredWidth(); 
      int activePage = ((scrollX + itemWidth/2)/itemWidth); 
      int scrollTo = activePage * itemWidth; 
      h_scroll.smoothScrollTo(scrollTo, 0); 


      //page control display the active page button 
      Log.v("MyDebug","Active page = "+activePage); 
      for(int i = 0; i < numberOfPages; i++){ 
       Button aPage = (Button) findViewById(i); 
       if(i == activePage){ 
        aPage.setBackgroundResource(thePage); 
       }else{ 
        aPage.setBackgroundResource(otherPage); 
       } 
      } 

      return true; 
     } else { 
      return false; 
     } 
    } 

}; 


//this is the onClick handler for the page buttons and moves the scroller to the page 
associated with the button. That is through the button ID, which matches the page 
number (0 based of course 

public void selectPage(View v) { 
    int newPage = v.getId(); 
    int itemWidth = h_scroll.getMeasuredWidth(); 
    int scrollTo = newPage * itemWidth; 
    h_scroll.smoothScrollTo(scrollTo, 0); 

    //page control display 
    Log.v("MyDebug","Active page = "+newPage); 
    for(int i = 0; i < numberOfPages; i++){ 
     Button aPage = (Button) findViewById(i); 
     if(i == newPage){ 
      aPage.setBackgroundResource(thePage); 
     }else{ 
      aPage.setBackgroundResource(otherPage); 
     } 
    } 
    } 

    public void finishActivity(View v){ 
     //perform back action 
     finish(); 
    } 

    public void nextActivity(View v){ 
     //move to next activity 
    } 
} 

Bueno, esa fue mi solución. Estoy seguro de que hay muchos programadores más inteligentes que yo, así que estoy seguro de que alguien puede mejorar esto. De todos modos GRACIAS stackoverflow !!!!

+2

Hola. Gracias por este contenido Sin embargo, debe proponer su solución como respuesta a su propia pregunta, tal como se aconseja aquí: http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/ –

+0

Amokrane, lo siento, ¿cómo puedo cambiar esto a un consejo? –

+0

Brian, simplemente deje la pregunta/problema como una pregunta y mueva la solución como una respuesta. –

Respuesta

0

Creo que la biblioteca GreenDroid ayudará a lograr algo similar al UIPageControl del iPhone.

Echa un vistazo a su aplicación en el mercado GDCatalog. También puede extraer los archivos que desee y crear el control de página. Lo he usado en mi aplicación y funciona bien. Necesita un poco de optimización para hacerlo más suave.

https://github.com/cyrilmottier/GreenDroid

Cuestiones relacionadas