1.TabActivity、视图树、动画

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

布局

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

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

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

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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
 <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
 <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >
 <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="gone" >
 </TabWidget>
 <!-- 自定义导航 -->
 <RelativeLayout 
			    android:layout_width="match_parent"
			    android:paddingTop="10dp"
			    android:paddingBottom="10dp"
			    android:layout_height="wrap_content"
			     android:background="@android:color/darker_gray"
 >
 <ImageView
			        android:id="@+id/iv_slide_backgrounp"//阴影图片
			        android:layout_width="wrap_content"
			        android:layout_height="wrap_content"
			        android:background="@drawable/slide_background" />
 <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >
 <!-- 第一个三分之一 -->
 <LinearLayout
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="2"
                    android:gravity="center_horizontal"
                    android:orientation="horizontal" >
 <!-- 会话标签 -->
 <LinearLayout
                        android:id="@+id/ll_conversation"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:orientation="vertical"
                        android:paddingLeft="10dp"
                        android:paddingRight="10dp" >
 <ImageView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:background="@drawable/tab_conversation" />
 <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="会话" />
 </LinearLayout>
 </LinearLayout>
 <!-- 第二个三分之一 -->
。。。。。。。
 <!-- 第三个三分之一 -->
   。。。。。。。。跟上面一样

 </LinearLayout>
 </RelativeLayout>
 <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >
 </FrameLayout>
 </LinearLayout>
 </TabHost>
</RelativeLayout>

代码:

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

public class MainActivity extends TabActivity implements OnClickListener {
	private TabHost tabHost;
	
	private LinearLayout llConversation;//会话
	private LinearLayout llFolder;//文件夹
	private LinearLayout llGroup;//群组
	
	private ImageView slideBackGround;//导航图片
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		tabHost = getTabHost();//直接get获取
		
		addTab("conversation","会话",R.drawable.tab_conversation,ConversationUI.class);
		addTab("folder","文件夹",R.drawable.tab_folder,FolderUI.class);
		addTab("group","群组",R.drawable.tab_group,GroupUI.class);//都是activity
		
		llConversation = (LinearLayout) findViewById(R.id.ll_conversation);
		llFolder = (LinearLayout) findViewById(R.id.ll_folder);
		llGroup = (LinearLayout) findViewById(R.id.ll_group);
		
		llConversation.setOnClickListener(this);
		llFolder.setOnClickListener(this);
		llGroup.setOnClickListener(this);
		
		slideBackGround = (ImageView) findViewById(R.id.iv_slide_backgrounp);
		
		// 此时 llConversation 仅仅创建了对象,还没有执行onMeasure 和 onLayout 方法 ,所以,此时  getWidth 返回值是0 
		//System.out.println("llConversation.getWidth()::"+llConversation.getWidth());
		
		// 获得全局viewTree的观察者,并添加 全局的layout监听
		llConversation.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
			
			@Override
			public void onGlobalLayout() {
				//由于此方法会执行多次,而我们只需要执行一次就可以了,
				//所以,在执行一次的时候,将全局的layout监听取消,,此处  this 指的是,内部的匿名对象
				llConversation.getViewTreeObserver().removeGlobalOnLayoutListener(this);
				
				System.out.println("llConversation.getWidth()::"+llConversation.getWidth());
				
				//设置图片的宽高,与会话标签相同
				int width = llConversation.getWidth();
				int height = llConversation.getHeight();
//slideBackGround的layoutParams 是没有leftMargin这个属性的,所以强转 
				RelativeLayout.LayoutParams layoutParams = (android.widget.RelativeLayout.LayoutParams) slideBackGround.getLayoutParams();
				layoutParams.width = width;
				layoutParams.height = height;
				
				//设置图片的左边距与会话的左边距相同
				int left = llConversation.getLeft();// 获得llConversation 在他的父view中左边距
				layoutParams.leftMargin =left; 
				
				// 将 llConversation的父view的宽度,设置给 itemLength,需要动态的变化
				itemLength = ((ViewGroup)llConversation.getParent()).getWidth();
			}
		});
	}
	
	/**
	 * 背景图片移动的单位宽度,即,屏幕的1/3
	 */
	private int itemLength;
	
	
	/**
	 * 给tabHost添加标签
	 * @param tag 	标签的命名
	 * @param label	标签显示的文字 
	 * @param iconId	标签显示的图标
	 * @param clazz		该标签对应的显示内容
	 */
	private void addTab(String tag, CharSequence label, int iconId, Class<?> clazz){
		
		//创建新的 标签    tag 是该标签的命名,此命名是tabHost用来管理标签的标示。
		TabSpec tabSpec =tabHost.newTabSpec(tag);
		//给标签添加 文字,和图标
		tabSpec.setIndicator(label, getResources().getDrawable(iconId));
		// 给标签添加对应的显示内容
		Intent intent = new Intent(this,clazz);
		tabSpec.setContent(intent);
		
		tabHost.addTab(tabSpec);
	}
	/**
	 * 滑动背景的上一个位置
	 */
	private int lastPosition;
	
	@Override
	/**
	 * 响应标签的点击事件
	 */
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.ll_conversation:// 会话标签 
			// 判断当前页面是否是 会话页面,如果不是,切换至会话页面,
			if(!"conversation".equals(tabHost.getCurrentTabTag())){
			
				tabHost.setCurrentTabByTag("conversation");
				
				slideBackGround.startAnimation(getAnim(0));
				
				lastPosition = 0;
				
			}
			
			break;
		case R.id.ll_folder:// 文件夹标签 
			
			// 判断当前页面是否是文件夹页面,如果不是,切换至
			if(!"folder".equals(tabHost.getCurrentTabTag())){
			
				tabHost.setCurrentTabByTag("folder");
				
				slideBackGround.startAnimation(getAnim(itemLength));
				
				lastPosition = itemLength;
			}
			break;
		case R.id.ll_group:// 群组标签 
			
			// 判断当前页面是否是文件夹页面,如果不是,切换至
			if(!"group".equals(tabHost.getCurrentTabTag())){
			
				tabHost.setCurrentTabByTag("group");
				
				slideBackGround.startAnimation(getAnim(itemLength*2));
				
				lastPosition = itemLength*2;
			}
			
			break;
		}
	}
	private TranslateAnimation getAnim(int destPosition) {
		
		TranslateAnimation anim = new TranslateAnimation(lastPosition, destPosition, 0, 0);
		anim.setDuration(500);
		anim.setFillAfter(true);
		return anim;
	}
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Felix的技术分享

Android滑动删除控件

2762
来自专栏移动开发

android 圆角图片的实现和封装

下面为主要源码,实现了 Picasso 中的 Transformation 接口。

2704
来自专栏Sorrower的专栏

Android绘制(一):来用shape绘出想要的图形吧!

2164
来自专栏Felix的技术分享

Android快速索引条控件QuickIndexBar

2637
来自专栏分享达人秀

ImageView的属性和方法大全

通过前面几期的学习,TextView控件及其子控件基本学习完成,可以在Android屏幕上显示一些文字或者按钮,那么从本期开始来学习如何进行图片展示,这...

1959
来自专栏Jack的Android之旅

模仿企鹅FM播放主页面滑动动态改变各视图的大小

国庆的一个任务就是把自己之前写的代码搬到博客。这次给各位带来的是通过滑动来动态改变各个View的大小进而达到企鹅FM播放页面的滑动效果(仅仅是滑动效果),老规矩...

1052
来自专栏everhad

[BOT]自定义ViewPagerStripIndicator

效果图 app中下面这样的控件很常见,像默认的TabHost表现上不够灵活,下面就简单写一个可以结合ViewPager切换内容显示,提供底部“滑动条”指示所显示...

2235
来自专栏学海无涯

Android开发之ListView使用经验分享

在Android开发中,ListView是使用最广泛的组件之一,虽然谷歌推出了RecycleView,但是很多项目中依旧在使用ListView,本文将总结一下使...

3236
来自专栏Android中高级开发

Android开发之漫漫长途 番外篇——自定义View的各种姿势1

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索...

1141
来自专栏郭霖

Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现

人人客户端有一个特效还是挺吸引人的,在主界面手指向右滑动,就可以将菜单展示出来,而主界面会被隐藏大部分,但是仍有左侧的一小部分同菜单一起展示。 据说人人客户端的...

28110

扫码关注云+社区

领取腾讯云代金券