1.TabActivity、视图树、动画

整个页面为TabActivity, 其中对TabWidget进行了一些改变,当切换页签时页签后面红色背景会以Translate动画形式移动到相对应的页签后。

布局

TabHost、TabWidget、FrameLayout的id必须是系统定义的,

因为可以直接get获取控件,上面的Tab标签一般不写原生的,自己写。

把原生的TabWidget隐藏,用了个垂直的LinearLayout写,

下面是FrameLayout,也是TabHost必须写的

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context=".MainActivity" >
  6. <TabHost
  7. android:id="@android:id/tabhost"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent" >
  10. <LinearLayout
  11. android:layout_width="match_parent"
  12. android:layout_height="match_parent"
  13. android:orientation="vertical" >
  14. <TabWidget
  15. android:id="@android:id/tabs"
  16. android:layout_width="match_parent"
  17. android:layout_height="wrap_content"
  18. android:visibility="gone" >
  19. </TabWidget>
  20. <!-- 自定义导航 -->
  21. <RelativeLayout
  22. android:layout_width="match_parent"
  23. android:paddingTop="10dp"
  24. android:paddingBottom="10dp"
  25. android:layout_height="wrap_content"
  26. android:background="@android:color/darker_gray"
  27. >
  28. <ImageView
  29. android:id="@+id/iv_slide_backgrounp"//阴影图片
  30. android:layout_width="wrap_content"
  31. android:layout_height="wrap_content"
  32. android:background="@drawable/slide_background" />
  33. <LinearLayout
  34. android:layout_width="match_parent"
  35. android:layout_height="wrap_content"
  36. android:orientation="horizontal" >
  37. <!-- 第一个三分之一 -->
  38. <LinearLayout
  39. android:layout_width="0dp"
  40. android:layout_height="wrap_content"
  41. android:layout_weight="2"
  42. android:gravity="center_horizontal"
  43. android:orientation="horizontal" >
  44. <!-- 会话标签 -->
  45. <LinearLayout
  46. android:id="@+id/ll_conversation"
  47. android:layout_width="wrap_content"
  48. android:layout_height="wrap_content"
  49. android:orientation="vertical"
  50. android:paddingLeft="10dp"
  51. android:paddingRight="10dp" >
  52. <ImageView
  53. android:layout_width="wrap_content"
  54. android:layout_height="wrap_content"
  55. android:background="@drawable/tab_conversation" />
  56. <TextView
  57. android:layout_width="wrap_content"
  58. android:layout_height="wrap_content"
  59. android:text="会话" />
  60. </LinearLayout>
  61. </LinearLayout>
  62. <!-- 第二个三分之一 -->
  63. 。。。。。。。
  64. <!-- 第三个三分之一 -->
  65. 。。。。。。。。跟上面一样
  66. </LinearLayout>
  67. </RelativeLayout>
  68. <FrameLayout
  69. android:id="@android:id/tabcontent"
  70. android:layout_width="match_parent"
  71. android:layout_height="match_parent" >
  72. </FrameLayout>
  73. </LinearLayout>
  74. </TabHost>
  75. </RelativeLayout>

代码:

阴影图片默认是这样的,用动画去动态的变化位置,其实图片还是在那了,只是个动画

  1. public class MainActivity extends TabActivity implements OnClickListener {
  2. private TabHost tabHost;
  3. private LinearLayout llConversation;//会话
  4. private LinearLayout llFolder;//文件夹
  5. private LinearLayout llGroup;//群组
  6. private ImageView slideBackGround;//导航图片
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. tabHost = getTabHost();//直接get获取
  12. addTab("conversation","会话",R.drawable.tab_conversation,ConversationUI.class);
  13. addTab("folder","文件夹",R.drawable.tab_folder,FolderUI.class);
  14. addTab("group","群组",R.drawable.tab_group,GroupUI.class);//都是activity
  15. llConversation = (LinearLayout) findViewById(R.id.ll_conversation);
  16. llFolder = (LinearLayout) findViewById(R.id.ll_folder);
  17. llGroup = (LinearLayout) findViewById(R.id.ll_group);
  18. llConversation.setOnClickListener(this);
  19. llFolder.setOnClickListener(this);
  20. llGroup.setOnClickListener(this);
  21. slideBackGround = (ImageView) findViewById(R.id.iv_slide_backgrounp);
  22. // 此时 llConversation 仅仅创建了对象,还没有执行onMeasure 和 onLayout 方法 ,所以,此时 getWidth 返回值是0
  23. //System.out.println("llConversation.getWidth()::"+llConversation.getWidth());
  24. // 获得全局viewTree的观察者,并添加 全局的layout监听
  25. llConversation.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
  26. @Override
  27. public void onGlobalLayout() {
  28. //由于此方法会执行多次,而我们只需要执行一次就可以了,
  29. //所以,在执行一次的时候,将全局的layout监听取消,,此处 this 指的是,内部的匿名对象
  30. llConversation.getViewTreeObserver().removeGlobalOnLayoutListener(this);
  31. System.out.println("llConversation.getWidth()::"+llConversation.getWidth());
  32. //设置图片的宽高,与会话标签相同
  33. int width = llConversation.getWidth();
  34. int height = llConversation.getHeight();
  35. //slideBackGround的layoutParams 是没有leftMargin这个属性的,所以强转
  36. RelativeLayout.LayoutParams layoutParams = (android.widget.RelativeLayout.LayoutParams) slideBackGround.getLayoutParams();
  37. layoutParams.width = width;
  38. layoutParams.height = height;
  39. //设置图片的左边距与会话的左边距相同
  40. int left = llConversation.getLeft();// 获得llConversation 在他的父view中左边距
  41. layoutParams.leftMargin =left;
  42. // 将 llConversation的父view的宽度,设置给 itemLength,需要动态的变化
  43. itemLength = ((ViewGroup)llConversation.getParent()).getWidth();
  44. }
  45. });
  46. }
  47. /**
  48. * 背景图片移动的单位宽度,即,屏幕的1/3
  49. */
  50. private int itemLength;
  51. /**
  52. * 给tabHost添加标签
  53. * @param tag 标签的命名
  54. * @param label 标签显示的文字
  55. * @param iconId 标签显示的图标
  56. * @param clazz 该标签对应的显示内容
  57. */
  58. private void addTab(String tag, CharSequence label, int iconId, Class<?> clazz){
  59. //创建新的 标签 tag 是该标签的命名,此命名是tabHost用来管理标签的标示。
  60. TabSpec tabSpec =tabHost.newTabSpec(tag);
  61. //给标签添加 文字,和图标
  62. tabSpec.setIndicator(label, getResources().getDrawable(iconId));
  63. // 给标签添加对应的显示内容
  64. Intent intent = new Intent(this,clazz);
  65. tabSpec.setContent(intent);
  66. tabHost.addTab(tabSpec);
  67. }
  68. /**
  69. * 滑动背景的上一个位置
  70. */
  71. private int lastPosition;
  72. @Override
  73. /**
  74. * 响应标签的点击事件
  75. */
  76. public void onClick(View v) {
  77. switch (v.getId()) {
  78. case R.id.ll_conversation:// 会话标签
  79. // 判断当前页面是否是 会话页面,如果不是,切换至会话页面,
  80. if(!"conversation".equals(tabHost.getCurrentTabTag())){
  81. tabHost.setCurrentTabByTag("conversation");
  82. slideBackGround.startAnimation(getAnim(0));
  83. lastPosition = 0;
  84. }
  85. break;
  86. case R.id.ll_folder:// 文件夹标签
  87. // 判断当前页面是否是文件夹页面,如果不是,切换至
  88. if(!"folder".equals(tabHost.getCurrentTabTag())){
  89. tabHost.setCurrentTabByTag("folder");
  90. slideBackGround.startAnimation(getAnim(itemLength));
  91. lastPosition = itemLength;
  92. }
  93. break;
  94. case R.id.ll_group:// 群组标签
  95. // 判断当前页面是否是文件夹页面,如果不是,切换至
  96. if(!"group".equals(tabHost.getCurrentTabTag())){
  97. tabHost.setCurrentTabByTag("group");
  98. slideBackGround.startAnimation(getAnim(itemLength*2));
  99. lastPosition = itemLength*2;
  100. }
  101. break;
  102. }
  103. }
  104. private TranslateAnimation getAnim(int destPosition) {
  105. TranslateAnimation anim = new TranslateAnimation(lastPosition, destPosition, 0, 0);
  106. anim.setDuration(500);
  107. anim.setFillAfter(true);
  108. return anim;
  109. }
  110. }

来自为知笔记(Wiz)

时间: 2024-10-26 22:01:28

1.TabActivity、视图树、动画的相关文章

监听视图树 OnGlobalLayoutListener

背景 我们都知道在onCreate()里面获取控件的高度是0,这是为什么呢?我们来看一下示例: 首先我们写一个控件 public class MyImageView extends ImageView {     public MyImageView(Context context, AttributeSet attrs) {         super(context, attrs);     }     public MyImageView(Context context) {       

iOS 视图,动画渲染机制探究

腾讯Bugly特约作者:陈向文 终端的开发,首当其冲的就是视图.动画的渲染,切换等等.用户使用 App 时最直接的体验就是这个界面好不好看,动画炫不炫,滑动流不流畅.UI就是 App 的门面,它的体验伴随着用户使用 App 的整个过程.如果UI失败,用户是不会有打开第二次的欲望的. iOS 为开发者提供了丰富的 Framework(UIKit,Core Animation,Core Graphic,OpenGL 等等)来满足开发从上层到底层各种各样的需求.不得不说苹果很牛逼,很多接口你根本不需要

iOS项目开发实战——实现视图切换动画

不同界面或者说不同视图之间进行切换是应用程序的一种最常见的动态效果,无论是哪一种平台的项目开发,默认的视图切换往往是十分单调的,没有任何动画的,界面的切换也是非常的突兀.如果说使用动画效果使界面能够活跃起来,那么你的App将会非常动感.这里将实现视图切换过程中的动画效果.具体实现如下: (1)本次试验将拖入2张图片,不直接放到View Controller中,而是在代码中动态加载.拖到Main.storyboard中后目录结构如下: . (2)实现图片与代码Outlet绑定: @IBOutlet

iOS Controller中视图切换动画效果

最近在一个小项目中遇到一个动画切换的效果,一时被难到了,后来又去看了下苹果公司提供的动画类,找到了几个动画的执行方法,这些默认的动画方法足够满足一般需求的动画效果了,接下来贴代码 首先我们在Controller中创建对应的按钮按钮 CGFloat mainHeight = [UIScreen mainScreen].bounds.size.height; NSArray titleArr = @[@"添加",@"翻页",@"移入",@"

CATransition:视图替换动画:子视图的增删查改

CATransition通常用于通过CALayer控制UIView内子控件的过渡动画,比如删除子控件,添加子控件,切换两个子控件等. 用于子视图的增删查改: 原文地址:https://www.cnblogs.com/feng9exe/p/10343076.html

ExpandableListView视图树简单应用

首先我们要自定义一个adapter来继承BaseExpandableListAdapter: package com.example.tree; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.AbsoluteLayout; import android.widget.AbsoluteLayout.LayoutParams;

简单通过Storyboard的Segue做视图切换动画

首先在storyboard里面定义连线,连的线,然后设置为custom的类型 然后新增一个UIStoryboardSegue的子类重写它的-(void)perform 方法 再把segue的属性segue class设置为你自己新建的那个segue的子类 -(void)perform{ UIViewController *dest = self.destinationViewController; UIViewController *src = self.sourceViewController

android视图切换动画:ViewAnimator类及其子类

类图:

iOS:UIView的block函数实现转场动画---双视图

使用UIView动画函数实现转场动画——双视图 + (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion; 参数说明: –duration:动画的持续时间 –options:转