项目中需要搭建布局,顶部右端按钮点击切换地图与列表,对应两个Fragment切换,整体框架是底部三个切换的按钮,分别对应着四个Fragment(有一个按钮对应两个Fragment,进行切换显示)。在其中一个Fragment中,顶部有四个切换的按钮,需要再对应四个Fragment,这样就涉及到Fragment嵌套Fragment的问题
界面图
说一下设计思路
第一张图,三个切换按钮,分别是”附近“,”充电“,”我的“,先new 两个Fragment,分别是ChargeFragment,MineFragment,对应”充电“与”我的“,这个”附近“按钮的布局比较特殊,点击右上角图标进行切换,需要两个Fragment进行切换,一个是地图MapFragment,一个是第二张图显示的布局NearByFragment,为了控制这五个Fragment,定义一个Controller类,用于创建,显示与隐藏Fragment,名字是FragmentController。第二张图NearByFragment又嵌套四个Fragment,创建四个Fragment:NearByDetailsFragment,EquipmentFragment,SortFragment,FilterFragment,创建一个控制类NearByFragmentController。
简单描述一下,主界面对应Fragments-
- ChargeFragment
- MineFragment
MapFragment(或NearByFragment)
NearByFragment对应Fragments-
- NearByDetailsFragment
- EquipmentFragment
- SortFragment
- FilterFragment
切换Fragment重新实例化的问题
Fragment创建完成,然后切换的时候,如果使用replace()方法切换,则会每次都重新实例化,比较耗资源,比较好的方法就是
先add()所有Fragment,切换时hide()其他Fragment,show()当前Fragment。
切换按钮的布局
看了网上的一些视频,视频中切换按钮使用了RadioGroup,发现效果还是不错的。为了更好的显现切换效果,需要在styles.xml中定义一个style,然后在drawable文件夹下,定义一个点击显现的xml,直接上代码
界面布局xml
<RadioGroup
android:id="@+id/rg_tab"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#fafafa"
android:gravity="center_vertical"
android:orientation="horizontal" >
<RadioButton
android:id="@+id/rb_near"
style="@style/RadioButtonBottomTab"
android:checked="true"
android:drawableTop="@drawable/icon_near"
android:text="@string/near" />
<RadioButton
android:id="@+id/rb_chargr"
style="@style/RadioButtonBottomTab"
android:drawableTop="@drawable/icon_charge"
android:text="@string/charge" />
<RadioButton
android:id="@+id/rb_mine"
style="@style/RadioButtonBottomTab"
android:drawableTop="@drawable/icon_mine"
android:text="@string/mine" />
</RadioGroup>
style.xml
<style name="RadioButtonBottomTab">
<item name="android:layout_weight">1</item>
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">match_parent</item>
<item name="android:button">@null</item>
<item name="android:textColor">@drawable/txtcolor_gray2oran_sel</item>
<item name="android:gravity">center</item>
<item name="android:background">@color/white</item>
</style>
drawable文件夹下txtcolor_gray2oran_sel.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:color="@color/orange" android:state_checked="true"></item>
<item android:color="@color/txt_gray" ></item>
</selector>
Fragment创建代码就不写了,先贴主界面控制类FragmentController
public class FragmentController {
private int containerId;
private FragmentManager fm;
private ArrayList<Fragment> fragments;
private static FragmentController controller;
public static FragmentController getInstance(FragmentActivity activity, int containerId) {
if (controller == null) {
controller = new FragmentController(activity, containerId);
}
return controller;
}
private FragmentController(FragmentActivity activity, int containerId) {
this.containerId = containerId;
fm = activity.getSupportFragmentManager();
initFragment();
}
private void initFragment() {
fragments = new ArrayList<Fragment>();
fragments.add(new MapFragment());
fragments.add(new ChargeFragment());
fragments.add(new MineFragment());
fragments.add(new NearByFragment());
FragmentTransaction ft = fm.beginTransaction();
for(Fragment fragment : fragments) {
ft.add(containerId, fragment);
}
ft.commit();
}
public void showFragment(int position) {
hideFragments();
Fragment fragment = fragments.get(position);
FragmentTransaction ft = fm.beginTransaction();
ft.show(fragment);
ft.commit();
}
public void hideFragments() {
FragmentTransaction ft = fm.beginTransaction();
for(Fragment fragment : fragments) {
if(fragment != null) {
ft.hide(fragment);
}
}
ft.commit();
}
public Fragment getFragment(int position) {
return fragments.get(position);
}
public static void destoryController(){
controller = null;
}
}
主界面相关代码
public class XXXXActivity extends FragmentActivity implements
RadioGroup.OnCheckedChangeListener {
private RadioGroup rg_tab;//底部选择框
private FragmentController controller;
public static String firstTabShow="MapFragment";//第一个Tab显示的Fragment,根据需要决定显示MapFragment或者NearByFragment
.....
//顶部右按钮点击切换两个Fragment
@Override
public void rightViewClick() {
rg_tab.getChildAt(0).performClick();
//两个Fragment相互切换
if(firstTabShow.equals("MapFragment")){
titleWithEditText.setRightShow(1);
titleWithEditText.setTextViewRightTitle("地图");
controller.showFragment(3);
firstTabShow="NearByFragment";
}else{
titleWithEditText.setRightShow(0);
controller.showFragment(0);
firstTabShow="MapFragment";
}
}
.....
titleWithEditText.setTitleLayoutListener(titleLayoutClick);
controller = FragmentController.getInstance(this, R.id.id_fragment);
controller.showFragment(0);
rg_tab = (RadioGroup) findViewById(R.id.rg_tab);
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.rb_near:
//两个Fragment相互切换
if(firstTabShow.equals("MapFragment")){
controller.showFragment(0);
}else{
controller.showFragment(3);
}
break;
case R.id.rb_chargr:
controller.showFragment(1);
break;
case R.id.rb_mine:
controller.showFragment(2);
break;
default:
break;
}
}
贴上NearByFragmentController代码
注意://fragment嵌套fragment,调用getChildFragmentManager
public class NearByFragmentController {
private int containerId;
private FragmentManager fm;
private ArrayList<Fragment> fragments;
private static NearByFragmentController controller;
public static NearByFragmentController getInstance(Fragment parentFragment, int containerId) {
if (controller == null) {
controller = new NearByFragmentController(parentFragment, containerId);
}
return controller;
}
private NearByFragmentController(Fragment fragment, int containerId) {
this.containerId = containerId;
//fragment嵌套fragment,调用getChildFragmentManager
fm = fragment.getChildFragmentManager();
initFragment();
}
private void initFragment() {
fragments = new ArrayList<Fragment>();
fragments.add(new NearByDetailsFragment());
fragments.add(new EquipmentFragment());
fragments.add(new SortFragment());
fragments.add(new FilterFragment());
FragmentTransaction ft = fm.beginTransaction();
for(Fragment fragment : fragments) {
ft.add(containerId, fragment);
}
ft.commit();
}
public void showFragment(int position) {
hideFragments();
Fragment fragment = fragments.get(position);
FragmentTransaction ft = fm.beginTransaction();
ft.show(fragment);
ft.commit();
}
public void hideFragments() {
FragmentTransaction ft = fm.beginTransaction();
for(Fragment fragment : fragments) {
if(fragment != null) {
ft.hide(fragment);
}
}
ft.commit();
}
public Fragment getFragment(int position) {
return fragments.get(position);
}
}
在NearByFragment类中进行切换控制,界面布局fragment_near_by.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="boerpower.com.boerchargingpile.UI.Fragments.NearByFragment">
<RadioGroup
android:id="@+id/rg_tab"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#fafafa"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_near"
style="@style/RadioButtonBottomTab"
android:checked="true"
android:drawableTop="@drawable/icon_near"
android:text="@string/near" />
<RadioButton
android:id="@+id/rb_equipment"
style="@style/RadioButtonBottomTab"
android:drawableTop="@drawable/icon_charge"
android:text="@string/equipment_top" />
<RadioButton
android:id="@+id/rb_sort"
style="@style/RadioButtonBottomTab"
android:drawableTop="@drawable/icon_mine"
android:text="@string/sort_top" />
<RadioButton
android:id="@+id/rb_filter"
style="@style/RadioButtonBottomTab"
android:drawableTop="@drawable/icon_mine"
android:text="@string/filter_top" />
</RadioGroup>
<FrameLayout
android:id="@+id/id_fragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
NearByFragment 代码
public class NearByFragment extends Fragment {
private RadioGroup rg_tab;//顶部选择框
private NearByFragmentController controller;
public NearByFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_near_by, container, false);
controller = NearByFragmentController.getInstance(this, R.id.id_fragment);
controller.showFragment(0);
rg_tab = (RadioGroup) view.findViewById(R.id.rg_tab);
rg_tab.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.rb_near:
controller.showFragment(0);
break;
case R.id.rb_equipment:
controller.showFragment(1);
break;
case R.id.rb_sort:
controller.showFragment(2);
break;
case R.id.rb_filter:
controller.showFragment(3);
break;
default:
break;
}
}
});
return view;
}
补充:
public class TitleWithEditText extends LinearLayout {
EditText editTextSearch;//搜索框
ImageView imageViewLeft;//左侧图片
ImageView imageViewRight;//右侧图片
TextView textViewRight;//右侧文本
FrameLayout frameLayoutRight;
private titleLayoutClick mListener;
public TitleWithEditText(final Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.title_with_edittext, this);
editTextSearch = (EditText) findViewById(R.id.id_editTextSearch);
imageViewLeft = (ImageView) findViewById(R.id.id_left);
imageViewRight = (ImageView) findViewById(R.id.id_rightImage);
textViewRight = (TextView) findViewById(R.id.id_rightText);
frameLayoutRight = (FrameLayout) findViewById(R.id.id_right);
imageViewRight.setVisibility(View.INVISIBLE);
textViewRight.setVisibility(View.INVISIBLE);
// textViewRight.setText("取消");
imageViewLeft.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mListener != null) {
mListener.leftViewClick();
}
}
});
frameLayoutRight.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mListener != null) {
mListener.rightViewClick();
}
}
});
editTextSearch.setInputType(InputType.TYPE_NULL);//设置输入类型为InputType.TYPE_NULL,禁止手机软键盘
editTextSearch.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//触碰输入框事件
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mListener != null) {
mListener.edittextClick();
}
}
return false;
}
});
}
//设置右侧显示的控件,图片或文本,viewId 0 显示图标,viewId 1 显示文本
public void setRightShow(int viewId) {
imageViewRight.setVisibility(View.INVISIBLE);
textViewRight.setVisibility(View.INVISIBLE);
if (viewId == 0) {
imageViewRight.setVisibility(View.VISIBLE);
} else if (viewId == 1) {
textViewRight.setVisibility(View.VISIBLE);
}
}
public void setTitleLayoutListener(titleLayoutClick titleLayoutListener) {
mListener = titleLayoutListener;
}
public void setTitleRightImage(int imageID){
imageViewRight.setBackgroundResource(imageID);
}
public interface titleLayoutClick {
public void leftViewClick();//左图片点击
public void rightViewClick();//右边点击
public void edittextClick();//点击搜索框事件
}
}
title_with_edittext
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/id_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical">
<ImageView
android:id="@+id/id_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="@mipmap/scan" />
</LinearLayout>
<EditText
android:id="@+id/id_editTextSearch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:background="@mipmap/search_bg"
android:drawableLeft="@mipmap/search"
android:drawablePadding="5dp"
android:paddingLeft="10dp"
android:hint="@string/title"
android:imeOptions="actionSearch"
android:inputType="text"
android:singleLine="true"
android:textColor="#000000"
android:textColorHint="#cccccc"
android:textSize="12sp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
<FrameLayout
android:id="@+id/id_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
>
<ImageView
android:id="@+id/id_rightImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
<TextView
android:id="@+id/id_rightText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#000000" />
</FrameLayout>
</LinearLayout>