在使用FragmentTabHost遇到了一些问题,记录下来,让那些踩坑的友人不在踏进去.在用FragmentTabHost这个控件时我一共遇到了三个问题:1tab不能控制上下,2分割线无法去掉
3缓存问题,针对这些问题,我来一一解决
1:控制tab可以上下:
tab控制上下是在布局文件里实现的:
如果居下:
<android.support.v4.app.FragmentTabHost/>节点下的<FrameLayout> 的宽高都为0,并且在<android.support.v4.app.FragmentTabHost/>节点外面定义新的<FrameLayout>,并在代码中tabhost.setup()方法中传入这个新如果居上:<FrameLayout>的ID则不用在<android.support.v4.app.FragmentTabHost/>节点外定义新的<FrameLayout>
tab居上
代码如下
<?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">
<android.support.v4.app.FragmentTabHost
android:id="@+id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--此处TabWidget可以省略不写,不写和写的效果一样-->
<TabWidget
android:id="@+id/tabwidget"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#f0f"></TabWidget>
<FrameLayout
android:id="@+id/tabcontent1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
</RelativeLayout>
tab居下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="business_android_client.myfirstndk.Main2Activity">
<!--这个是真正填充Fragment的布局-->
<FrameLayout
android:id="@+id/realcontent3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<android.support.v4.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!--此处TabWidget省略不写没关系
<FrameLayout/>高度宽度必须为0,否则不能正常显示Fragment
-->
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp">
</FrameLayout>
</android.support.v4.app.FragmentTabHost></LinearLayout>
实现tab居上居下和布局文件有关系,下面就要实现tab和Fragment绑定,代码都是一样的只有核心的两行代码
tabhost.setup()
tabhost.addTab()
tab居上绑定
public class MainActivity extends AppCompatActivity {
private FrameLayout tabcontent;
private TabWidget tabwidget;
private FragmentTabHost tabhost;
private String[] titles = {"首页", "第二页", "第三页", "第四页"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
Class [] fragments = {fragment1.class, fragment2.class, fragment3.class,
fragment4.class};
private void initView() {
tabhost = (FragmentTabHost) findViewById(R.id.tabhost);
tabhost.setup(this,getSupportFragmentManager(),R.id.tabcontent1);
tabhost.getTabWidget().setDividerDrawable(android.R.color.transparent);
for (int i=0;i<4;i++) {
View view = View.inflate(this, R.layout.item_table,null);
TextView text = (TextView) view.findViewById(R.id.textView1);
text.setText(titles[i]);
tabhost.addTab(tabhost.newTabSpec("" + i).setIndicator(view),fragments[i], null);
}
}
}
tab居下绑定
public class Main2Activity extends AppCompatActivity {
private FrameLayout realcontent;
private FragmentTabHost tabhost;
String[] title = {"one", "two", "three"};
Class[] fragments = {fragment1.class, fragment2.class, fragment3.class};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initView();
}
private void initView() {
tabhost = (FragmentTabHost) findViewById(android.R.id.tabhost);
//设置无分割线
tabhost.setup(this,getSupportFragmentManager(),R.id.realcontent3);
tabhost.getTabWidget().setDividerDrawable(android.R.color.transparent);
for (int i=0;i<3;i++) {
View view = View.inflate(this, R.layout.item_table, null);
TextView tv = (TextView) view.findViewById(R.id.textView1);
tv.setText(title[i]);
TabHost.TabSpec tabSpec = tabhost.newTabSpec(""+title[i]).setIndicator(view);
tabhost.addTab(tabSpec, fragments[i],null);
}
}
}
这里就实现了居上居下,那每次点击tab时都会重新创建fragment,非常耗费资源,并且不能保存之前的数据,所有要缓存fragment
禁止重新创建fragment
第二:带缓存的Fragment
BaseFragment
public abstract class BaseFragment extends Fragment {
public Context context;
private View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(view==null){
context = getActivity();
view = View.inflate(getActivity(), getLayoutResId(), null);
//1. 查找控件
initView(view);
//2. 设置监听
initListener();
//3. 设置数据
initData();
}
//缓存的rootView需要判断是否已经被加过parent, 如果有parent需要从parent删除,要不然会发生这个rootview已经有parent的错误。
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null) {
parent.removeView(view);
}
return view;
}
/**
* 获取当前fragment对应的布局id
* @return
*/
public abstract int getLayoutResId() ;
/**
* 初始化view:
* 查找控件
* @param view
*/
public abstract void initView(View view) ;
/**
* 初始化监听
*/
public abstract void initListener() ;
/**
* 初始化数据
* 给控件设置内容
*/
public abstract void initData() ;
}
if(view==null){}
parent.removeView(view);
就是判断当前的Fragment已经被创建后,view不为空,返回第一次的创建的view,并且把原来的view从父布局中移除否则会保存:your view Already have a parent,please
remove it befroe add view
第三去除分割线
去掉分割线:
tabhost.getTabWidget().setDividerDrawable(android.R.color.transparent);
如果你看到这行代码然后感觉贴上去运行,发现没有任何毛用,这个时间问题.只有当
tabhost.setup()执行完后,再去执行设置分割线才有用
这个顺序是对的
tabhost = (FragmentTabHost) findViewById(android.R.id.tabhost);
tabhost.setup(this,getSupportFragmentManager(),R.id.realcontent3);
tabitem布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/tabselector_drawable"
android:id="@+id/imageView"
/>
<TextView
android:text="TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView1"
android:textColor="@drawable/tableselecter_text"
/>
</LinearLayout>