草庐IT

Android页面控件像iPhone页面控件

coder 2023-12-06 原文

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

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

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

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

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

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

前 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(将添加到每个配方步骤的滚动部分的 View 。请注意,滚动部分在 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(将添加到每个配方步骤的分页器部分的 View 。请注意,每一个都将在 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!!!!

最佳答案

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

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

https://github.com/cyrilmottier/GreenDroid

关于Android页面控件像iPhone页面控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10469232/

有关Android页面控件像iPhone页面控件的更多相关文章

  1. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  2. ruby - 在 ASP 页面上 Mechanize 中断 - 2

    require'mechanize'agent=Mechanize.newlogin=agent.get('http://www.schoolnet.ch/DE/HomeDE.htm')agent.clicklogin.link_withtext:/Login/然后我得到Mechanize::UnsupportedSchemeError。 最佳答案 Mechanize不支持javascript但您可以将搜索字段添加到表单并为其分配搜索词并使用mechanize提交表单form=page.forms.firstform.add_fie

  3. ruby-on-rails - prawnto 显示新页面时不会中断的表格 - 2

    我有可变数量的表格和可变数量的行,我想让它们一个接一个地显示,但如果表格不适合当前页面,请将其放在下一页,然后继续。我已将表格放入事务中,以便我可以回滚然后打印它(如果高度适合当前页面),但我如何获得表格高度?我现在有这段代码pdf.transactiondopdf.table@data,:font_size=>12,:border_style=>:grid,:horizontal_padding=>10,:vertical_padding=>3,:border_width=>2,:position=>:left,:row_colors=>["FFFFFF","DDDDDD"]pdf.

  4. ruby - 每个页面上的 Jekyll 分页 - 2

    据我们所知,Jekyll默认分页仅支持index.html,我想创建blog.html并在那里包含分页。有什么解决办法吗? 最佳答案 如果您创建一个名为/blog的目录并在其中放置一个index.html文件,那么您可以向_config.yml表示paginate_path:"blog/page:num"。不是使用根文件夹中的默认index.html作为分页器模板,而是使用/blog/index.html。分页器将根据需要生成类似/blog/page2/和/blog/page3/的页面。这将使您到达yourwebsite.com/b

  5. ruby-on-rails - RoR && "coming soon"页面 - 2

    我正在寻找一种简单的方法来为我在RubyonRails上的项目实现简单的“即将推出”(预启动)页面。用户应该能够留下电子邮件以便在项目启动时收到通知。有没有这样的插件\gem?或者我应该自己做... 最佳答案 LaunchingSoon是一个Rails插件。它还集成了MailChimp或Campaignmonitor. 关于ruby-on-rails-RoR&&"comingsoon"页面,我们在StackOverflow上找到一个类似的问题: https:/

  6. ruby - 如何让 GitHub 页面使用 master 分支? - 2

    我有一个使用Jekyll托管在GitHub上的静态网站。问题是,我真的不需要master分支,因为存储库唯一包含的是网站。这样我就必须gitcheckoutgh-pages,然后gitmergemaster,然后gitpushorigingh-pages。有什么简单的方法可以摆脱gh-pages分支并直接从master推送? 最佳答案 Theproblemis,Idon'treallyneedthemasterbranch,astheonlythingtherepositorycontainsisthewebsite.Isthere

  7. ruby - 如何设置 Mechanize 页面编码? - 2

    我试图通过点击一个链接获得一个带有ISO-8859-1编码的页面,所以代码类似于这样:page_result=page.link_with(:text=>'link_text').click到目前为止,我得到的结果编码错误,所以我看到的字符如下:'T�tulo:'insteadof'Título:'我尝试了几种方法,包括:使用代理在第一个请求中声明编码:@page_search=@agent.get(:url=>'http://www.server.com',:headers=>{'Accept-Charset'=>'ISO-8859-1'})说明页面本身的编码page_result.

  8. ruby-on-rails - 仅在某些页面上使用 rails_xss - 2

    我正在使用rails_xss运行Rails2.3.14插入。我有另一个用于创建管理仪表板View的插件。我的问题是rails_xss正在转义我的仪表板插件生成的所有HTML。有没有一种方法可以将rails_xss配置为不转义匹配example.com/admin或基于目录(app/views/admin)或任何类似的页面结果一样吗? 最佳答案 更新仪表板生成插件以使用raw或html_safe进行内容输出可能会更简单。 关于ruby-on-rails-仅在某些页面上使用rails_xss

  9. ruby-on-rails - 在多个页面上使用相同表单的 Rails 最佳实践 - 2

    我正在开发一个Rails2.3.1网站。在整个网站中,我需要一个用于在各种页面(主页、创建帖子页面、帖子列表页面、评论列表页面等)上创建帖子的表单——只要说这个表单需要在由各种Controller)。这些页面中的每一个都显示在相应的Controller/操作中检索到的各种其他信息。例如,主页列出了最新的10篇文章、从数据库中提取的内容等。因此,我已将帖子创建表单移动到它自己的部分中,并将该部分包含在所有必要的页面中。请注意,部分POST中的表单到/questions(路由到PostsController::create——这是默认的Rails行为)。我遇到的问题是当Posts表单没有正

  10. ruby - 如何在转换器插件中访问页面属性(YAML 前端) - 2

    我正在为Jekyll编写一个转换器插件,需要访问一些页眉(YAML前端)属性。只有内容被传递给主要的转换器方法,似乎无法访问上下文。例子:moduleJekyllclassUpcaseConverter关于如何在转换器插件中访问页眉数据有什么想法吗? 最佳答案 基于Jekyll源代码,无法在转换器中检索YAML前端内容。根据您的情况,我看到了两种可行的解决方案。您的文件扩展名可以具有足够的描述性,以提供您本应包含在前言中的信息。看起来Converter插件的设计就是这么基本的。如果修改Jekyll是一个选项,您可以更改Convert

随机推荐