65.9K
CodeProject 正在变化。 阅读更多。
Home

Android: 类似新闻和天气视图的 ViewFlipper 触摸动画

2010年3月30日

CPOL

6分钟阅读

viewsIcon

121969

Android: 类似新闻和天气视图的 ViewFlipper 触摸动画

引言

在本教程中,我们将学习如何解决 Android 项目中一个常见的问题。若想获取更多关于 Android 项目的信息,我建议您下载 ADT Android 插件和 Eclipse。让我们从 Android 开发的一些基础知识开始。

背景

要开始 Android 开发,您需要三个重要的东西:Android SDK(您可以在这里下载)、一个项目编辑器(我推荐 Eclipse)和 Android Eclipse 插件

当您准备好环境后,就可以开始本教程了。

第一次打开 Android SDK 时,您需要创建一个虚拟设备。我建议创建一个通用设备,将 Android 1.6 API Level 4 作为目标,然后添加您环境中需要的硬件功能,例如:SD 卡支持、加速计、相机支持等。如果您在启动 Android 虚拟设备方面需要帮助,请访问此链接

开始 Eclipse 项目

按照以下简单步骤在 Eclipse 中创建 Android 项目

  1. 选择 文件 > 新建 > 项目
  2. 选择 Android > Android 项目,然后单击 下一步
  3. 选择项目内容
    • 输入项目名称。这将是创建项目文件夹的名称。
    • 在“内容”下,选择在工作区中创建新项目。选择您的项目工作区位置。
    • 在“目标”下,选择一个 Android 目标作为项目的构建目标。构建目标指定您希望您的应用程序基于哪个 Android 平台构建。

      除非您知道您将使用最新 SDK 中引入的新 API,否则您应该选择一个平台版本最低的目标,例如 Android 1.6。

      注意:您可以随时更改项目的构建目标:右键单击“包资源管理器”中的项目,选择 属性,选择 Android,然后勾选所需项目目标。

    • 在“属性”下,填写所有必需字段。
      • 输入应用程序名称。这是您应用程序的用户可读标题,也是将在 Android 设备上显示的名称。
      • 输入程序包名称。这是所有源代码所在的程序包命名空间(遵循 Java 编程语言中程序包的相同规则)。
      • 选择创建 Activity(当然是可选的,但很常见),然后为您的主 Activity 类输入名称。
      • 输入最小 SDK 版本。这是一个整数,表示正确运行您的应用程序所需的最低 API 级别。在此处输入此值会自动设置 Android Manifest 文件中 <uses-sdk> 的 minSdkVersion 属性。如果您不确定要使用的 API 级别,请复制“目标”选项卡中您选择的构建目标所列的 API 级别。
  4. 点击**完成**。
准备就绪后,ADT 会为您创建以下文件夹和文件
  • src/:包含任何 Activity Java 文件。您应用程序的所有其他 Java 文件都放在这里。
  • <Android 版本>:包含您的应用程序将以此为基础构建的 android.jar 文件。这由您在新建项目向导中选择的构建目标决定。
  • gen/:包含 ADT 生成的 Java 文件,例如您的 R.java 文件以及从 AIDL 文件创建的接口(这是一个自动类)。
  • assets/:此文件夹为空。您可以使用它来存储原始资源文件。
  • res/:用于放置应用程序资源的文件夹,例如可绘制文件、布局文件、字符串值等。
  • AndroidManifest.xml:您项目的 Android Manifest 文件。
  • default.properties:此文件包含项目设置,例如构建目标。此文件是项目不可或缺的一部分,因此应将其维护在源代码版本控制系统中。切勿手动编辑此文件 — 要编辑项目属性,请右键单击项目文件夹并选择“属性”。

在本教程中,我们只使用两个文件夹:src/res/,现在开始解决常见问题的示例解决方案。

如何通过触摸事件滑动两个(或更多)布局,就像新闻和天气应用一样

现在您已经准备好 Android 环境,在 Android 开发中,我们首先尝试模仿最佳应用程序的图形效果。因此,最常用且效果最佳的动画/事件之一就是通过手指从一个 Activity 滑动到另一个 Activity。要实现这一点,我们需要一点 Java 代码和一些 XML 布局技巧。

从 XML 布局文件开始

res/layout/ 打开 main.xml(或其他布局文件),然后粘贴以下代码: 

<ViewFlipper
    android:layout_margin="6dip"
    android:id="@+id/layoutswitcher"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <TextView
            android:layout_height="wrap_content"
            android:id="@+id/firstpanel"
            android:paddingTop="10dip"
            android:text="my first panel"
            android:layout_width="fill_parent"
            android:layout_weight="1"
            android:textStyle="bold" >
        </TextView>
    </LinearLayout>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <TextView
            android:layout_height="wrap_content"
            android:id="@+id/secondpanel"
            android:paddingTop="10dip"
            android:text="my second panel"
            android:layout_width="fill_parent"
            android:layout_weight="1"
            android:textStyle="bold" >
        </TextView>
    </LinearLayout>
</ViewFlipper>

如您所见,我添加了一个 ViewFlipper,两个 LinearLayout,并在每个内部布局中添加了一个 simpletextview。第一步是创建适当的切换布局所必需的,之后您可以根据需要自定义两个内部布局的样式,如果需要,还可以添加一个工具栏来在内部布局之间切换。

第二步:Java 代码(通过触摸切换布局) 

现在从 src/<您的程序包名称> 打开您的主类,并在类开头声明这两个变量: 

    private ViewFlipper vf;  
    private float oldTouchValue;

第一个变量 (VF) 用于控制 ViewFlipper,第二个变量用于触摸事件。现在将 viewflipper 附加到类。

     public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ....
		vf = (ViewFlipper) findViewById(R.id.switchlayout);
     }

现在我们已经声明了 viewflipper,可以继续进行这个简单教程的最后一步了。

触摸事件

这款新型手机最重要的功能之一就是触摸屏系统,就像 iPhone 应用或其他触摸设备一样,用户更喜欢用手指在 Activity 之间切换。在 Android 开发中,附加触摸事件可以做两件事:“实现 touchlistener”或通过覆盖主方法声明 onTouchEvent

在此示例中,我们使用第二种情况。请看以下代码,然后是说明。

    @Override
    public boolean onTouchEvent(MotionEvent touchevent) {
        switch (touchevent.getAction())
        {
            case MotionEvent.ACTION_DOWN:
            {
                oldTouchValue = touchevent.getX();
                break;
            }
            case MotionEvent.ACTION_UP:
            {
                if(this.searchOk==false) return false;
                float currentX = touchevent.getX();
                if (oldTouchValue < currentX)
                {
                    vf.setInAnimation(AnimationHelper.inFromLeftAnimation());
                    vf.setOutAnimation(AnimationHelper.outToRightAnimation());
                    vf.showNext();
                }
                if (oldTouchValue > currentX)
                {
                    vf.setInAnimation(AnimationHelper.inFromRightAnimation());
                    vf.setOutAnimation(AnimationHelper.outToLeftAnimation());
                    vf.showPrevious();
                }
            break;
            }
        }
        return false;
    }

如您所见,当用户第一次触摸设备时,浮点变量 (oldTouchValue) 会存储其手指的 X 位置。然后,当用户释放手指时,我会检查事件的新位置来决定用户是想去下一个还是上一个(oldTouchValue < currentX, oldTouchValue > currentX)。要更改布局,代码相同,但我使用不同的动画来区分用户是想去下一个还是上一个。有关动画和 AnimationHelper 的更多说明,我在此处提供了示例代码。

	//for the previous movement
	public static Animation inFromRightAnimation() {

    	Animation inFromRight = new TranslateAnimation(
    	Animation.RELATIVE_TO_PARENT,  +1.0f, Animation.RELATIVE_TO_PARENT,  0.0f,
    	Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,   0.0f
    	);
    	inFromRight.setDuration(350);
    	inFromRight.setInterpolator(new AccelerateInterpolator());
    	return inFromRight;
    	}
    public static Animation outToLeftAnimation() {
    	Animation outtoLeft = new TranslateAnimation(
    	 Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,  -1.0f,
    	 Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,   0.0f
    	);
    	outtoLeft.setDuration(350);
    	outtoLeft.setInterpolator(new AccelerateInterpolator());
    	return outtoLeft;
    	}    
    // for the next movement
    public static Animation inFromLeftAnimation() {
    	Animation inFromLeft = new TranslateAnimation(
    	Animation.RELATIVE_TO_PARENT,  -1.0f, Animation.RELATIVE_TO_PARENT,  0.0f,
    	Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,   0.0f
    	);
    	inFromLeft.setDuration(350);
    	inFromLeft.setInterpolator(new AccelerateInterpolator());
    	return inFromLeft;
    	}
    public static Animation outToRightAnimation() {
    	Animation outtoRight = new TranslateAnimation(
    	 Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,  +1.0f,
    	 Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,   0.0f
    	);
    	outtoRight.setDuration(350);
    	outtoRight.setInterpolator(new AccelerateInterpolator());
    	return outtoRight;
    	}

您可以选择将这些方法放在一个静态类中(像我一样),或者在您的类中声明它们。

结论

现在您已经有了基础类和用于捕获从右到左(show.previous)和从左到右(show.next)触摸移动的事件,以及一个简单的代码来解释这四种动画移动和一个简单的布局供您尝试。我建议您使用两个以上的布局和更复杂的内容进行进一步测试。这只是 Android 功能的一个示例,但我认为您可以找到更强大的解决方案!

© . All rights reserved.