Android自定义TabActivity(实现仿新浪微博底部菜单更新UI)

如今Android上很多应用都采用底部菜单控制更新的UI这种框架,例如新浪微博

点击底部菜单的选项可以更新界面。底部菜单可以使用TabHost来实现,不过用过TabHost的人都知道自定义TabHost究竟是有多麻烦的,原生TabHost的风格是不依附屏幕的底部的,要依附底部就要重写布局。

TabHost设置的Container可以管理UI的显示,UI可以用LayoutInflater动态生成,也可以是Activity,但不好管理Activity的生命周期。然后用TabHost控制显示UI的显示。

下面使用的一种方法是自定义菜单布局+ActivityGroup+多个Activity的方式实现,下面是Demo的截图:

          

ActivityGroup

ActivityGroup,顾名思义就是Activity组,可以管理多个Activity的启动和销毁。ActivityGroup是继承Activity的,但是这个方法目前已经被弃用了,虽然不推荐使用,不过还是可以用的。以后会讲推荐的做法。我们会用这个类管理界面的实现。ActivityGroup中有一个重要的方法是getLocalActivityManager,这个方法可以销毁和启动新的Activity,并可以通过getDecorView方法获取到启动Activity的根视图显示出来。Activity显示在ActivityGroup中的一个container中,而container是显示Activity的一个区域,这个container必须是ViewGroup或者是其子类。

首先编写一个TabActivity

package com.shamoo.activity;

import android.app.ActivityGroup;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;

public class TabActivity extends ActivityGroup {

	private ViewGroup container;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
	}

	/**
	 * 通过id设置Activity显示的container,该container必须是继承ViewGroup的
	 */
	protected void setContainer(int resId) {
		container = (ViewGroup) findViewById(resId);
	}

	/**
	 * 通过Activity的class显示Activity
	 */
	protected void showActivity(Class<?> activityClass) {

		Intent intent = new Intent(this, activityClass);
		// 检查container是否有显示的Activity,如果有,先移除
		View activity = container.getChildAt(0);
		if (activity != null) {
			// 移除显示的activity的View
			container.removeAllViews();
			// 通过ActivityManager移除activity
			getLocalActivityManager().removeAllActivities();
		}
		// 启动新的activity,并将该activity的根视图添加到contanier中
		container.addView(getLocalActivityManager().startActivity(activityClass.getName(), intent).getDecorView());
	}

}

编写一个继承TabActivity的MainActivity管理界面,界面是三个Activity

package com.shamoo.activity;

import com.shamoo.activitygroupdemo.R;

import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends TabActivity implements OnClickListener {

	/**
	 * 显示的三个Activity的class
	 */
	private Class<?> activities[] = {OneActivity.class, TwoActivity.class, ThreeActivity.class};

	/**
	 * 菜单的三个按钮
	 */
	private Button[] btn = new Button[3];

	/**
	 * 当前的选择
	 */
	private int currentSelect;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		setContentView(R.layout.activity_main);
		setContainer(R.id.fl_container);
		btn[0] = (Button) findViewById(R.id.btn_one);
		btn[0].setOnClickListener(this);
		btn[1] = (Button) findViewById(R.id.btn_two);
		btn[1].setOnClickListener(this);
		btn[2] = (Button) findViewById(R.id.btn_three);
		btn[2].setOnClickListener(this);
		showActivity(activities[0]);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		btn[currentSelect].setBackgroundResource(R.color.normal);
		switch (v.getId()) {
		case R.id.btn_one:
			currentSelect = 0;
			btn[0].setBackgroundResource(R.color.select);
			showActivity(activities[0]);
			break;
		case R.id.btn_two:
			currentSelect = 1;
			btn[1].setBackgroundResource(R.color.select);
			showActivity(activities[1]);
			break;
		case R.id.btn_three:
			currentSelect = 2;
			btn[2].setBackgroundResource(R.color.select);
			showActivity(activities[2]);
			break;
		}
	}

}

编写activity_main.xml,该布局有底部菜单的实现,是通过LinearLayout的layout_weight配合修改背景的Button实现的

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/rl_menu"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >
        <Button
            android:id="@+id/btn_one"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#008eff"
            android:text="1" />
        <Button
            android:id="@+id/btn_two"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#555555"
            android:text="2" />
        <Button
            android:id="@+id/btn_three"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#555555"
            android:text="3" />
    </LinearLayout>

    <FrameLayout
        android:id="@+id/fl_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/rl_menu" >

    </FrameLayout>
</RelativeLayout>

然后编写三个Activity,这三个Activity可以自定义。代码比较多,就不全贴出来了。

启动Demo之后,可以看到Activity的生命周期管理是没有问题的

Demo下载链接:http://download.csdn.net/detail/stephenzcl/7306531

Android自定义TabActivity(实现仿新浪微博底部菜单更新UI)

时间: 2024-10-25 09:45:38

Android自定义TabActivity(实现仿新浪微博底部菜单更新UI)的相关文章

Android自定义View之仿QQ侧滑菜单实现

最近,由于正在做的一个应用中要用到侧滑菜单,所以通过查资料看视频,学习了一下自定义View,实现一个类似于QQ的侧滑菜单,顺便还将其封装为自定义组件,可以实现类似QQ的侧滑菜单和抽屉式侧滑菜单两种菜单. 下面先放上效果图: 我们这里的侧滑菜单主要是利用HorizontalScrollView来实现的,基本的思路是,一个布局中左边是菜单布局,右边是内容布局,默认情况下,菜单布局隐藏,内容布局显示,当我们向右侧滑,就会将菜单拉出来,而将内容布局的一部分隐藏,如下图所示: 下面我们就一步步开始实现一个

Android自定义控制(五)仿新浪微博的下拉刷新

网上有很多很有名的开源框架,这里就来拉拉PullToRefresh这个框架,也就是我们平时用的下拉刷新啦,当然你问我这个有什么用啊?别人已经写好了,这里主要是学习以及练习,练习的次数多了,一切就顺其自然的会了. 废话少说,先上图,再上代码: 1.要想实现下拉刷新功能必须要有个下拉刷新的布局,是吧? <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="htt

android 自定义标签的使用,实现扁平化UI设计

2014年8月6日11:06:44 android对自定义标签的使用,实现扁平化UI设计: 1.attrs.xml文件中自定义标签 如: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="first"> //reference指的是是从string.xml引用过来 <attr name="nam

Android学习笔记48:使用Handler实时更新UI

在Android中,主要通过MessageQueue.Looper和Handler三个类来实现Android应用程序的消息处理.其中,MessageQueue类用来描述消息队列:Looper类用来创建消息队列,以及进入消息循环:Handler类则用来发送消息和接收消息. 本文将主要对Handler进行简要介绍,并以一个简单的实例演示如何使用Handler实时更新UI. 1.Handler的作用 在Android中,当应用程序启动时,Android系统会启动一个主线程(也被称为UI线程),主要用来

Android异步处理二:使用AsyncTask异步更新UI界面

Android异步处理二:使用AsyncTask异步更新UI界面 - lzc的专栏 - 博客频道 - CSDN.NET 在<Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面>中,我们使用Thread+Handler的方式实现了异步更新UI界面,这一篇中,我们介绍一种更为简洁的实现方式:使用AsyncTask异步更新UI界面. 概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的

安卓开发复习笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)

记得之前写过2篇关于底部菜单的实现,由于使用的是过时的TabHost类,虽然一样可以实现我们想要的效果,但作为学习,还是需要来了解下这个新引入类FragmentTabHost 之前2篇文章的链接: 安卓开发复习笔记——TabHost组件(一)(实现底部菜单导航) 安卓开发复习笔记——TabHost组件(二)(实现底部菜单导航) 关于Fragment类在之前的安卓开发复习笔记——Fragment+ViewPager组件(高仿微信界面)也介绍过,这里就不再重复阐述了. 国际惯例,先来张效果图: 下面

转-Fragment+FragmentTabHost组件(实现新浪微博底部菜单)

http://www.cnblogs.com/lichenwei/p/3985121.html 记得之前写过2篇关于底部菜单的实现,由于使用的是过时的TabHost类,虽然一样可以实现我们想要的效果,但作为学习,还是需要来了解下这个新引入类FragmentTabHost 之前2篇文章的链接: 安卓开发复习笔记——TabHost组件(一)(实现底部菜单导航) 安卓开发复习笔记——TabHost组件(二)(实现底部菜单导航) 关于Fragment类在之前的安卓开发复习笔记——Fragment+Vie

Android自定义view之仿支付宝芝麻信用仪表盘

自定义view练习 仿支付宝芝麻信用的仪表盘 对比图: 首先是自定义一些属性,可自己再添加,挺基础的,上代码 <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RoundIndicatorView"> <!--最大数值--> <attr name="maxNum" form

Android 自定义View,仿微信视频播放按钮

闲着,尝试实现了新版微信视频播放按钮,使用的是自定义View,先来个简单的效果图...真的很简单哈. 由于暂时用不到,加上时间原因,加上实在是没意思,加上……,本控件就没有实现自定义属性,有兴趣的朋友可以自己去添加一下,方法都给你们准备好了.- = 其实这个控件主要步骤 1.画外环的圆 2.画进度的圆或者画三角形播放按钮 其余剩下的都是围绕以上两步准备或者收尾的. 接下来贴主要我们的自定义控件代码,注释很全,我就不过多解释了,请各位看官自己分析,有疑问可以在评论区一起讨论. package co