在项目开发中,遇到这样一个问题场景:在某个页面(Fragament)中,点击按钮,进行页面部分的切换,即在一个Fragament中嵌套使用了两个Fragament进行切换。
设置按钮监听首先在布局文件中,给两个进行切换的按钮标记id:button_user、button_shop;
并添加需要动态填充的布局(id为id_role)
<Button
android:id="@+id/button_user"
android:layout_width="100dp"
android:layout_height="30dp"
android:background="@drawable/button_circle2"
android:text="我是用户"
android:textColor="@color/bar"
android:textSize="12sp"
android:paddingTop="-10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_marginLeft="70dp"/>
<Button
android:id="@+id/button_shop"
android:layout_width="100dp"
android:layout_height="30dp"
android:background="@drawable/button_circle"
android:text="我是商家"
android:textColor="@color/white"
android:textSize="12sp"
android:paddingTop="-10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_marginLeft="20dp"/>
<LinearLayout
android:id="@+id/id_role"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
LinearLayout>
在主控的Fragment文件中调用接口 View.OnClickListener
public class page fragment extends Fragment implements View.OnClickListener{
...
}
在onActivityCreated中绑定按钮并设置按钮监听:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Button button_user = (Button) getActivity().findViewById(R.id.button_user);
Button button_shop = (Button) getActivity().findViewById(R.id.button_shop);
button_user.setOnClickListener(this);
button_shop.setOnClickListener(this);
}
覆写接口的onClick方法
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button_user:
Log.d("Number","1");
break;
case R.id.button_shop:
Log.d("Number","2");
break;
default:
break;
}
}
至此,按钮监听设置完成。
Fragment切换要实现Fragment的切换,使用FragmentManager
类来管理fragment,对fragment的 *** 作(添加、删除、替换等)称为一个事务,通过FragmentTransaction类来提交执行。(类似数据库中的事务概念)
几个关键方法
add()
:添加
hide()
:隐藏
show()
:显示
replace()
:替换
关于Fragment 生命周期/事物管理的更详细的信息可参考这篇博文Fragment的基本应用
简要来说,实现fragment切换主要步骤为:
1.实例化对象fragmentTransaction
2.隐藏当前已显示的fragment
3.对需要动态添加的fragment进行判断,如果没有,使用add添加;如果已有,直接显示。
4.提交事务
相关代码如下:
private void hideFragment(FragmentTransaction fragmentTransaction) {
if(imshop != null){
fragmentTransaction.hide(imshop);
}
if(imuser != null){
fragmentTransaction.hide(imuser);
}
}
@Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
hideFragment(fragmentTransaction);
switch (v.getId()){
case R.id.button_user:
if(imuser == null){
imuser imuser = new imuser();
fragmentTransaction.replace(R.id.id_role,imuser);
}else {
fragmentTransaction.show(imuser);
}
break;
case R.id.button_shop:
if(imshop == null){
imshop imshop = new imshop();
fragmentTransaction.replace(R.id.id_role,imshop);
}else {
fragmentTransaction.show(imshop);
}
break;
default:
break;
}
fragmentTransaction.commit();
}
其中,imuser/imshop 为我需要添加的两个Fragment的类对象。
这里我遇到了一个小问题,使用add进行添加后,并不能完成切换,但替换成replace之后便可实现切换,具体原因待考究。
点击按钮进行界面切换是瞬间完成的,对于用户来说,体验并不良好。因此可以简单添加两个左移、右移的动画来进行过渡,使体验更为丝滑。
首先建立动画文件,在res下创建文件夹anim。
先考虑一个左移动画,主要可拆分成两个步骤:1.当前页面向左划出。2.之后页面向右划入。
因此建立两个文件:
左移划出:slide_out_to_left.xml
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="400"
android:fromXDelta="0.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toXDelta="-100%" />
右移划入:slide_in_from_right
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="400"
android:fromXDelta="100.0%"
android:interpolator="@android:anim/accelerate_interpolator"
android:toXDelta="0.0"
/>
这里参数简单说明一下:
duration:表示动画持续时间(毫秒)
fromXDelta:滑动起始点
toXDelta:滑动终点
更多属性可参考这篇文章Android动画
上面两个步骤实现了左滑,同样,右滑只需要修改坐标值即可。
左移划入slide_in_from_left.xml
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="400"
android:fromXDelta="-100%"
android:interpolator="@android:anim/accelerate_interpolator"
android:toXDelta="0.0"
/>
右移划出slide_out_to_right.xml
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="400"
android:fromXDelta="0.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toXDelta="100%" />
设置完之后,重新修改控制文件,只需添加 fragmentTransaction.setCustomAnimations属性。
@Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
hideFragment(fragmentTransaction);
switch (v.getId()){
case R.id.button_user:
if(imuser == null){
imuser imuser = new imuser();
fragmentTransaction.setCustomAnimations(R.anim.slide_in_from_right, R.anim.slide_out_to_left);
fragmentTransaction.replace(R.id.id_role,imuser);
}else {
fragmentTransaction.show(imuser);
}
break;
case R.id.button_shop:
if(imshop == null){
imshop imshop = new imshop();
fragmentTransaction.setCustomAnimations(R.anim.slide_in_from_left, R.anim.slide_out_to_right);
fragmentTransaction.replace(R.id.id_role,imshop);
}else {
fragmentTransaction.show(imshop);
}
break;
default:
break;
}
fragmentTransaction.commit();
}
效果演示:
常规Activity多个Fragment切换设计导航栏时经常采用在Activity中进行多个Fragment切换,实际上和在Fragment进行设计大同小异。这里放置一个案例可供参考。
main.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bg">
<LinearLayout
android:id="@+id/id_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
LinearLayout>
<include layout="@layout/bottom" />
FrameLayout>
bottom.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="66dp"
android:gravity="center"
android:orientation="horizontal"
android:background="@color/white"
android:layout_gravity="bottom">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/id_tab1"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:id="@+id/id_tab_img1"
android:clickable="false"
android:layout_width="28dp"
android:layout_height="28dp"
android:src="@drawable/home"
android:scaleType="fitXY"
android:background="#00000000"/>
LinearLayout>
<LinearLayout
android:id="@+id/id_tab2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:id="@+id/id_tab_img2"
android:clickable="false"
android:layout_width="28dp"
android:layout_height="28dp"
android:scaleType="fitXY"
android:src="@drawable/product"
android:background="#00000000"/>
LinearLayout>
<LinearLayout
android:id="@+id/id_add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:id="@+id/id_tab_add"
android:clickable="false"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/add"
android:scaleType="fitXY"
android:background="#00000000"/>
LinearLayout>
<LinearLayout
android:id="@+id/id_tab3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:id="@+id/id_tab_img3"
android:clickable="false"
android:layout_width="28dp"
android:layout_height="28dp"
android:src="@drawable/community"
android:scaleType="fitXY"
android:background="#00000000"/>
LinearLayout>
<LinearLayout
android:id="@+id/id_tab4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:id="@+id/id_tab_img4"
android:clickable="false"
android:layout_width="28dp"
android:layout_height="28dp"
android:src="@drawable/me"
android:scaleType="fitXY"
android:background="#00000000"/>
LinearLayout>
LinearLayout>
MainActivity.java
package cn.edu.cdut.goat;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.LocalActivityManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
import cn.edu.cdut.goat.R;
public class MainActivity extends FragmentActivity implements View.OnClickListener {
//声明四个Tab的布局文件
private LinearLayout mTab1;
private LinearLayout mTab2;
private LinearLayout mTab3;
private LinearLayout mTab4;
//声明四个Tab的ImageButton
private ImageButton mImg1;
private ImageButton mImg2;
private ImageButton mImg3;
private ImageButton mImg4;
//声明四个Tab分别对应的Fragment
private Fragment mFrag1;
private Fragment mFrag2;
private Fragment mFrag3;
private Fragment mFrag4;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 隐藏标题栏
setContentView(R.layout.activity_main);
initViews();//初始化控件
initEvents();//初始化事件
selectTab(0);//默认选中第一个Tab
}
private void initEvents(){
//初始化四个Tab的点击事件
mTab1.setOnClickListener(this);
mTab2.setOnClickListener(this);
mTab3.setOnClickListener(this);
mTab4.setOnClickListener(this);
}
private void initViews(){
//初始化四个Tab的布局文件
mTab1=(LinearLayout)findViewById(R.id.id_tab1);
mTab2=(LinearLayout)findViewById(R.id.id_tab2);
mTab3=(LinearLayout)findViewById(R.id.id_tab3);
mTab4=(LinearLayout)findViewById(R.id.id_tab4);
//初始化四个ImageButton
mImg1=(ImageButton)findViewById(R.id.id_tab_img1);
mImg2=(ImageButton)findViewById(R.id.id_tab_img2);
mImg3=(ImageButton)findViewById(R.id.id_tab_img3);
mImg4=(ImageButton)findViewById(R.id.id_tab_img4);
}
//处理Tab的点击事件
@SuppressLint("NonConstantResourceId")
@Override
public void onClick(View v){
resetImgs(); //先将四个ImageButton置为灰色
switch(v.getId()){
case R.id.id_tab1:
selectTab(0);
break;
case R.id.id_tab2:
selectTab(1);
break;
case R.id.id_tab3:
selectTab(2);
break;
case R.id.id_tab4:
selectTab(3);
break;
}
}
//进行选中Tab的处理
private void selectTab(int i){
//获取FragmentManager对象
FragmentManager manager=getSupportFragmentManager();
//获取FragmentTransaction对象
FragmentTransaction transaction=manager.beginTransaction();
//先隐藏所有的Fragment
hideFragments(transaction);
switch(i){
//当选中点击的是第一页的Tab时
case 0:
//设置第一页的ImageButton为绿色
mImg1.setImageResource(R.drawable.home_select);
//如果第一页对应的Fragment没有实例化,则进行实例化,并显示出来
if(mFrag1==null){
mFrag1=new pageFragment1();
transaction.add(R.id.id_content,mFrag1);
}else{
//如果第一页对应的Fragment已经实例化,则直接显示出来
transaction.show(mFrag1);
}
break;
case 1:
mImg2.setImageResource(R.drawable.product_select);
if(mFrag2==null){
mFrag2=new pageFragment2();
transaction.add(R.id.id_content,mFrag2);
}else{
transaction.show(mFrag2);
}
break;
case 2:
mImg3.setImageResource(R.drawable.community_select);
if(mFrag3==null){
mFrag3=new pageFragment3();
transaction.add(R.id.id_content,mFrag3);
}else{
transaction.show(mFrag3);
}
break;
case 3:
mImg4.setImageResource(R.drawable.me_select);
if(mFrag4==null){
mFrag4=new pageFragment4();
transaction.add(R.id.id_content,mFrag4);
}else{
transaction.show(mFrag4);
}
break;
}
//不要忘记提交事务
transaction.commit();
}
//将四个的Fragment隐藏
private void hideFragments(FragmentTransaction transaction){
if(mFrag1!=null){
transaction.hide(mFrag1);
}
if(mFrag2!=null){
transaction.hide(mFrag2);
}
if(mFrag3!=null){
transaction.hide(mFrag3);
}
if(mFrag4!=null){
transaction.hide(mFrag4);
}
}
//将四个ImageButton置为灰色
private void resetImgs(){
mImg1.setImageResource(R.drawable.home);
mImg2.setImageResource(R.drawable.product);
mImg3.setImageResource(R.drawable.community);
mImg4.setImageResource(R.drawable.me);
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)