【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
微信、QQ、微博底部等都有 Tab 标签选项,点击不同的标签可以切换的不同的界面。
步骤
1)描述主界面布局
activity_main.xml 代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@drawable/header_bg" >
<RelativeLayout
android:id="@+id/left_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >
<ImageView
android:id="@+id/left_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/left_ico" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/library_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >
<ImageView
android:id="@+id/library_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/library_ico" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/local_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >
<ImageView
android:id="@+id/local_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/local_ico" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/news_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >
<ImageView
android:id="@+id/news_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/news_ico" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/search_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >
<ImageView
android:id="@+id/search_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/search_ico" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
</LinearLayout>
说明:代码可能看着有点长,先看下布局之后的 outline 和 可视化编辑区效果:(仿“网易云音乐界面”)
- 主体分为 LinearLayout 和 FrameLayout(id=connect),分别放置 Tab 标签按钮和对应内容
- LinearLayout 中分 5 个部分(左侧菜单栏left、乐库library、本地音乐local、动态news)
- (本次实例主要实现中间 3 个 Tab导航即可)
2)设置每个 Fragment 的布局
library_layout.xml 代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/library_bg">
</LinearLayout>
说明:放置了一张背景图片 library_bg.png,其他两个布局相似
local_layout.xml 与 news_layout.xml 代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/local_bg">
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/news_bg" >
</LinearLayout>
3)创建对应布局的 Fragment 类(继承于 Fragment)
LibraryFragment.java 代码如下:
public class LibraryFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View libraryLayout =inflater.inflate(R.layout.library_layout, container,false);
return libraryLayout;
}
}
说明:新建类继承于 Fragment,其他两个类相似
LocalFragmet.java 与 NewsFragment.java 代码如下:
public class LocalFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View localLayout =inflater.inflate(R.layout.local_layout, container,false);
return localLayout;
}
}
public class NewsFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View newsLayout =inflater.inflate(R.layout.news_layout, container,false);
return newsLayout;
}
}
4)在 MainActivity.java 中添加响应代码
MainActivity.java 代码如下:
public class MainActivity extends Activity implements OnClickListener{
/*
* 用于展示的Fragment
*/
private LibraryFragment libraryFragment;
private LocalFragment localFragment;
private NewsFragment newsFragment;
/*
* 界面布局
*/
private View libraryLayout;
private View localLayout;
private View newsLayout;
/*
* 在Tab布局上显示图标的控件
*/
private ImageView libraryImage;
private ImageView localImage;
private ImageView newsImage;
/*
* 用于对Fragment进行管理
*/
private FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
// 初始化布局元素(方法实现在下面的代码)
initViews();
fragmentManager = getFragmentManager();
// 第一次启动时选中第0个tab(方法实现在下面的代码)
setTabSelection(0);
}
/*
* 在这里获取到每个需要用到的控件的实例,并给它们设置好必要的点击事件。
*/
private void initViews() {
libraryLayout = findViewById(R.id.library_layout);
localLayout = findViewById(R.id.local_layout);
newsLayout = findViewById(R.id.news_layout);
libraryImage = (ImageView) findViewById(R.id.library_image);
localImage = (ImageView) findViewById(R.id.local_image);
newsImage = (ImageView) findViewById(R.id.news_image);
libraryLayout.setOnClickListener(this);
localLayout.setOnClickListener(this);
newsLayout.setOnClickListener(this);
}
/*
* 点击事件的响应代码
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.library_layout:
// 当点击了第0个tab时,选中第1个tab
setTabSelection(0);
break;
case R.id.local_layout:
// 当点击了第1个tab时,选中第2个tab
setTabSelection(1);
break;
case R.id.news_layout:
// 当点击了第2个tab时,选中第3个tab
setTabSelection(2);
break;
default:
break;
}
}
/**
* 根据传入的index参数来设置选中的tab页。
*
* @param index:每个tab页对应的下标。0表示乐库,1表示本地,2表示动态
*
*
*/
private void setTabSelection(int index) {
// 每次选中之前先清楚掉上次的选中状态
clearSelection();
// 开启一个Fragment事务
FragmentTransaction transaction = fragmentManager.beginTransaction();
// 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况
hideFragments(transaction);
switch (index) {
case 0:
// 当点击了乐库tab时,改变控件的图片颜色
libraryImage.setImageResource(R.drawable.library_selected);
// libraryTitle.setTextColor(Color.RED);
if (libraryFragment == null) {
// 如果LibraryFragment为空,则创建一个并添加到界面上
libraryFragment = new LibraryFragment();
transaction.add(R.id.content, libraryFragment);
} else {
// 如果LibraryFragment不为空,则直接将它显示出来
transaction.show(libraryFragment);
}
break;
case 1:
// 当点击了本地tab时,改变控件的图片颜色
localImage.setImageResource(R.drawable.local_selected);
// localTitle.setTextColor(Color.RED);
if (localFragment == null) {
// 如果LocalFragment为空,则创建一个并添加到界面上
localFragment = new LocalFragment();
transaction.add(R.id.content, localFragment);
} else {
// 如果LocalFragment不为空,则直接将它显示出来
transaction.show(localFragment);
}
break;
case 2:
// 当点击了动态tab时,改变控件的图片颜色
newsImage.setImageResource(R.drawable.news_selected);
// newsTitle.setTextColor(Color.RED);
if (newsFragment == null) {
// 如果NewsFragment为空,则创建一个并添加到界面上
newsFragment = new NewsFragment();
transaction.add(R.id.content, newsFragment);
} else {
// 如果NewsFragment不为空,则直接将它显示出来
transaction.show(newsFragment);
}
break; }
transaction.commit();
}
/**
* 清除掉所有的选中状态。
*/
private void clearSelection() {
libraryImage.setImageResource(R.drawable.library_ico);
localImage.setImageResource(R.drawable.local_ico);
newsImage.setImageResource(R.drawable.news_ico);
}
/**
* 将所有的Fragment都置为隐藏状态。
*
* @param transaction :用于对Fragment执行操作的事务
*/
private void hideFragments(FragmentTransaction transaction) {
if (libraryFragment != null) {
transaction.hide(libraryFragment);
}
if (localFragment != null) {
transaction.hide(localFragment);
}
if (newsFragment != null) {
transaction.hide(newsFragment);
}
}
}
代码有点长,但是注释很详细,简单整理一下
- initView():获取控件的实例并为其注册点击事件监听器
- onClick(View v):点击事件的响应代码
- setTabSelection(int index):根据 index 确定被选中的 Tad
- clearSelection():清除 Tab 被选中的状态
- hideFragment():将对应的 Fragment 设置为隐藏状态
说明:监听到点击事件,就响应 onClick() 中相应的代码,即把对应 Tab 状态改变:“未选中”→“选中”,同时显示对应的 Fragment 至 id 为 connect 的 FrameLayout 布局上;但在此之前需要清除之前的选中状态以及隐藏之前显示的 Fragment 。
示例程序
(仿 网易云音乐)点击中间三个图标,切换到各自界面;
附:目录结构
方法参考: Android Fragment应用实战,使用碎片向ActivityGroup说再见
来源:oschina
链接:https://my.oschina.net/u/2866387/blog/794403