6

我想把一些东西放回这个非常有用的网站,所以这不是一个真正的问题,而是我对这个问题的解决方案。我还要补充一点,这个解决方案是从本网站和许多其他网站的支持中收集到的,因此它代表了许多其他开发人员的共同努力。我对他们说声谢谢!

问题是“如何在 Android 环境中重新创建 iPhone 应用程序的水平滚动视图方面和相关的页面控件?”

这是因为我想在单个滚动视图中显示配方中的步骤、每个步骤的相关方法以及必要的成分。我还想要一个页面控件向用户显示他们在步骤中的位置,并允许他们移动到任何特定步骤

我的应用程序的这一部分显示了食谱中的步骤。每个步骤都出现在一个页面上,并包含三个组件。步骤标识符(即步骤 1、步骤 2)、步骤所需的方法和成分。

在配方部分下方,我们显示一个页面控件,该控件显示哪个页面处于活动状态并且可用于导航到特定页面。您会注意到页面控件具有图像按钮,并且两个图像是简单的圆圈,一个用于非选定页面(page.png),一个用于选定页面(page_selected.png)

创建活动时,将从数据中检索所选配方的步骤,并通过为配方中的每个步骤添加视图来创建滚动条部分。当您滑动滚动条时,视图会捕捉到下一页或上一页,并且寻呼机显示会更新以指示您所在的页面

前 3 个 xml 布局(res/layout)

食谱.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(将添加到每个配方步骤的滚动部分的视图。请注意,滚动部分在 recipeViewController.java 中有一个 onTouchlistner 来处理页面滚动)

<?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 (将添加到每个配方步骤的寻呼机部分的视图。请注意,这些视图中的每一个都将在 recipeViewController.java 中有一个 onClick 事件,该事件将滚动到寻呼机控件中选择的特定页面)

<?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>

这一切都汇集在 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
  }
}

那是我的解决方案。我确信有很多比我聪明的程序员,所以我相信有人可以改进这一点。无论如何感谢stackoverflow!!!!

4

1 回答 1

0

我认为 GreenDroid 库将有助于实现类似于 iPhone 的 UIPageControl 的功能。

在市场 GDDatalog 中查看他们的应用程序。您还可以提取所需的文件并制作页面控件。我已经在我的应用程序中使用了它,它工作正常。需要进行一些优化以使其更流畅。

https://github.com/cyrilmottier/GreenDroid

于 2012-08-10T09:11:16.120 回答