Android Fragment实现QQ的主界面功能

Fragment的利用越来越多了,QQ、新浪微博,支付宝的主界面,都可以用Fragment来实现。

现在,我们就利用Fragment来实现QQ的主界面功能,先上图:

我们可以看到,在QQ主界面的下面,有一行tab,有四个选项,可以实现切换。

新建一个项目,起名为FragmentDemoDemo。创建或者打开activity_main.xml作为程序的主布局文件,加入如下代码:

<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <FrameLayout 
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"  >    
    </FrameLayout>
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="@drawable/tab_bg" >
        
        <RelativeLayout
            android:id="@+id/message_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/message_image"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:src="@drawable/message_unselected" />
                
                <TextView
                    android:id="@+id/message_text" 
                    android:layout_width="wrap_content"  
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:text="消息"
                    android:textColor="#82858b"/>         
                           
            </LinearLayout>
            
        </RelativeLayout>
        
        <RelativeLayout
            android:id="@+id/contacts_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/contacts_image"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:src="@drawable/contacts_unselected" />
                
                <TextView
                    android:id="@+id/contacts_text" 
                    android:layout_width="wrap_content"  
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:text="联系人"
                    android:textColor="#82858b"/>         
                           
            </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_unselected" />
                
                <TextView
                    android:id="@+id/news_text" 
                    android:layout_width="wrap_content"  
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:text="动态"
                    android:textColor="#82858b"/>         
                           
            </LinearLayout>
            
        </RelativeLayout>
        
        <RelativeLayout
            android:id="@+id/setting_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/setting_image"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:src="@drawable/setting_unselected" />
                
                <TextView
                    android:id="@+id/setting_text" 
                    android:layout_width="wrap_content"  
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:text="设置"
                    android:textColor="#82858b" />         
                           
            </LinearLayout>
            
        </RelativeLayout>
              
    </LinearLayout>
    
</LinearLayout>

这个主布局文件里面,由两部分组成。第一部分是FrameLayout,里面的内容,可以在后面动态添加。第二部分是FrameLayout下面的LinearLayout,这个LinearLayout就是类似TabHost的布局。这个LinearLayout被分成四份,每一份里面多有一个ImageView和一个TextVIew,分别用来显示图标和文字。

已经分成了四份,那我们现在就分别实现四个Fragment和它们的布局了。新建一个message_xml作为消息界面的布局,加入如下代码:

<?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:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_centerInParent="true"
       android:orientation="vertical" >
    
          <ImageView 
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:src="@drawable/message_selected"/>
    
          <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:padding="10dp"
             android:text="这是消息界面"
             android:textSize="20sp"/>
     </LinearLayout>
</RelativeLayout>

这个布局比较简单,只是在中间显示一个图标和一些文字。

现在来创建这个布局相对应的Fragment。新建MessageFragment继承Fragment,加入如下代码:

package com.cfy.fragmentdemodemo;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MessageFragment extends Fragment{

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View messageLayout = inflater.inflate(R.layout.message_layout, container, false);
		return messageLayout;
	}     
}

后面三个是类似的。

新建contacts_xml作为联系人界面的布局,加入如下代码:

<?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:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_centerInParent="true"
       android:orientation="vertical" >
    
          <ImageView 
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:src="@drawable/contacts_selected"/>
    
          <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:padding="10dp"
             android:text="这是联系人界面"
             android:textSize="20sp"/>
     </LinearLayout>
</RelativeLayout>

再新建ContactsFragment继承Fragment,加入如下代码:

package com.cfy.fragmentdemodemo;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class ContactsFragment extends Fragment{

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View contactsLayout = inflater.inflate(R.layout.contacts_layout, container, false);
		return contactsLayout;
	}
}

新建news_layout.xml作为动态界面的布局,加入如下代码:

<?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:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_centerInParent="true"
       android:orientation="vertical" >
    
          <ImageView 
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:src="@drawable/news_selected"/>
    
          <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:padding="10dp"
             android:text="这是动态界面"
             android:textSize="20sp"/>
     </LinearLayout>
</RelativeLayout>

新建NewsFragment继承Fragment,加入如下代码:

package com.cfy.fragmentdemodemo;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class NewsFragment extends Fragment{

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View newsLayout = inflater.inflate(R.layout.news_layout, container, false);
		return newsLayout;
	}
}

新建setting_layout.xml作为设置界面的布局,加入如下代码:

<?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:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_centerInParent="true"
       android:orientation="vertical" >
    
          <ImageView 
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:src="@drawable/setting_selected"/>
    
          <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:padding="10dp"
             android:text="这是设置界面"
             android:textSize="20sp"/>
     </LinearLayout>
</RelativeLayout>

新建SettingFragment继承Fragment,加入如下代码:

package com.cfy.fragmentdemodemo;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class SettingFragment extends Fragment{

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View settingLayout = inflater.inflate(R.layout.setting_layout, container, false);
		return settingLayout;
	}
}

现在我们已经把四个Fragment都创建好了,以及它们所对应的布局文件。

接下来,我们新建或者打开MainActivity作为主Activity,加入如下代码:

package com.cfy.fragmentdemodemo;

import android.os.Bundle;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.graphics.Color;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;

/*
 * 项目的主Activity,所有的Fragment都嵌入到这里。
 * @author cfy
 */
public class MainActivity extends Activity implements OnClickListener {
	/*
	 * 定义消息、联系人、动态、设置的Fragment
	 */
	private MessageFragment messageFragment;
	private ContactsFragment contactsFragment;
	private NewsFragment newsFragment;
	private SettingFragment settingFragment;
	
	/*
	 * 定义消息、联系人、动态、设置的fragment的布局
	 */
	private View messageLayout;
	private View contactsLayout;
	private View newsLayout;
	private View settingLayout;
	
	/*
	 * 定义消息、联系人、动态、设置的tab的图标
	 */
	private ImageView messageImage;
	private ImageView contactsImage;
	private ImageView newsImage;
	private ImageView settingImage;
	
	/*
	 * 定义消息、联系人、动态、设置的tab的文本
	 */
	private TextView messageText;
	private TextView contactsText;
	private TextView newsText;
	private TextView settingText;
	
	/*
	 * 对Fragment进行管理
	 */
	private FragmentManager fragmentManager;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		initViews(); //初始化界面,并设置四个tab的监听
	    fragmentManager = getFragmentManager();
		setTabSelection(0); //第一次启动时开启第0个tab
		
	}
	
    /*
     * 根据传入的index,来设置开启的tab页面
     * @param index
     * index代表对应的下标,0对应消息,1对应联系人,2对应动态,3对应设置
     */
	private void setTabSelection(int index) {
		// TODO Auto-generated method stub
		//清理之前的所有状态
		clearSelection();
		//开启一个Fragment事务
		FragmentTransaction transaction = fragmentManager.beginTransaction();
		//隐藏所有的fragment,防止有多个界面显示在界面上
		hideFragments(transaction);
		switch(index){
		case 0:
			//当点击消息tab时,改变控件的图片和文字颜色
			messageImage.setImageResource(R.drawable.message_selected);
			messageText.setTextColor(Color.WHITE);
			//如果messageFragment为空,则创建一个添加到界面上
			if(messageFragment == null){
				messageFragment = new MessageFragment();
				transaction.add(R.id.content, messageFragment);
			} else {
				//如果messageFragment不为空,则直接将它显示出来
				transaction.show(messageFragment);
			}
			break;
		case 1:
			//当点击联系人tab时,改变控件的图片和文字颜色
			contactsImage.setImageResource(R.drawable.contacts_selected);
			contactsText.setTextColor(Color.WHITE);
			//如果contactsFragment为空,则创建一个添加到界面上
			if(contactsFragment == null){
				contactsFragment = new ContactsFragment();
				transaction.add(R.id.content, contactsFragment);
			} else {
				//如果contactsFragment不为空,则直接将它显示出来
				transaction.show(contactsFragment);
			}
			break;
		case 2:
			//当点击动态tab时,改变控件的图片和文字颜色
			newsImage.setImageResource(R.drawable.news_selected);
			newsText.setTextColor(Color.WHITE);
			//如果newsFragment为空,则创建一个添加到界面上
			if(newsFragment == null){
				newsFragment = new NewsFragment();
				transaction.add(R.id.content, newsFragment);
			} else {
				transaction.show(newsFragment);
			}
			break;
		case 3:
	    default:
			//当点击设置tab时,改变控件的图片和文字颜色
			settingImage.setImageResource(R.drawable.setting_selected);
			settingText.setTextColor(Color.WHITE);
			//如果settingFragment为空,则创建一个添加到界面上
			if(settingFragment == null){
				settingFragment = new SettingFragment();
				transaction.add(R.id.content, settingFragment);
			} else {
				transaction.show(settingFragment);
			}
			break;		
		}
		transaction.commit();
	}
 
	/*
	 * 隐藏所有的fragment
	 * @param transaction
	 *     用于对fragment进行操作的事务
	 */
	private void hideFragments(FragmentTransaction transaction) {
		// TODO Auto-generated method stub
		if(messageFragment != null){
			transaction.hide(messageFragment);
		}
		if(contactsFragment != null){
			transaction.hide(contactsFragment);
		}
		if(newsFragment != null){
			transaction.hide(newsFragment);
		}
		if(settingFragment != null){
			transaction.hide(settingFragment);
		}
	}

	/*
	 * 清理之前的所有状态
	 */
	private void clearSelection() {
		// TODO Auto-generated method stub
		messageImage.setImageResource(R.drawable.message_unselected);
		messageText.setTextColor(Color.parseColor("#82858b"));
		contactsImage.setImageResource(R.drawable.contacts_unselected);
		contactsText.setTextColor(Color.parseColor("#82858b"));
		newsImage.setImageResource(R.drawable.news_unselected);
		newsText.setTextColor(Color.parseColor("#82858b"));
		settingImage.setImageResource(R.drawable.setting_unselected);
		settingText.setTextColor(Color.parseColor("#82858b"));
	}

	/*
	 * 初始化界面,并设置四个tab的监听
	 */
	private void initViews() {
		// TODO Auto-generated method stub
		messageLayout = findViewById(R.id.message_layout);
		contactsLayout = findViewById(R.id.contacts_layout);
		newsLayout = findViewById(R.id.news_layout);
		settingLayout = findViewById(R.id.setting_layout);
		
		messageImage = (ImageView) findViewById(R.id.message_image);
		contactsImage = (ImageView) findViewById(R.id.contacts_image);
		newsImage = (ImageView) findViewById(R.id.news_image);
		settingImage = (ImageView) findViewById(R.id.setting_image);
		
		messageText = (TextView) findViewById(R.id.message_text);
		contactsText = (TextView) findViewById(R.id.contacts_text);
		newsText = (TextView) findViewById(R.id.news_text);
		settingText = (TextView) findViewById(R.id.setting_text);
		
		messageLayout.setOnClickListener(this);
		contactsLayout.setOnClickListener(this);
		newsLayout.setOnClickListener(this);
		settingLayout.setOnClickListener(this);		
	}

	/*
	 * 点击四个tab时的监听
	 * @param v
	 *     四个控件的view
	 */
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId()){
		case R.id.message_layout:
			//点击消息tab,选中第一个tab
			setTabSelection(0);
			break;
		case R.id.contacts_layout:
			//点击联系人tab,选中第二个tab
			setTabSelection(1);
			break;
		case R.id.news_layout:
			//点击动态tab,选中第三个tab
			setTabSelection(2);
			break;
		case R.id.setting_layout:
			//点击设置tab,选中第四个tab
			setTabSelection(3);
			break;
		default:
			break;
		}
	}
}

代码已经注释得很详细了,到此为主,程序已经写完了。

现在,我们已经使用Fragment编写出和TabHost一样的效果了。每个界面的具体逻辑就可以写在相应的Fragment中了,效果跟写在Activity中类似。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值