FragmentTabHost使用注意:tab居上居下,分割线,Fragment缓存

在使用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>










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值