基于androidx的Fragment使用,Fragment嵌套TabLayout+Fragment+ViewPager

从不久之前,我把我的android stuidio软件更新到3.几来着,就是google新出的androidx环境,写项目的时候发现,Fragment的导包居然有两个,刚开始使用android下面的包,会出现方法过期,怎么看怎么不顺眼,然后就导入androidx,一系列报错,这是最尴尬的!

比如:

private var mfragmentManager: FragmentManager? = null
mfragmentManager = getSupportFragmentManager();  //获得FragmentManager的对象

可不能使用之前的 getChildFragmentManager() 以及getFragmentManager(),首先你这个activity还得继承

 FragmentActivity(),注意是导包
import androidx.fragment.app.FragmentActivity

主要就是这个,接下来看代码:

package com.airiche.nixplay.Activity

import android.content.Intent
import android.os.Bundle
import com.airiche.nixplay.MainApplication

import android.util.Log
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import com.airiche.nixplay.FragMent.FriendsFragment
import com.airiche.nixplay.FragMent.MoreFragment
import com.airiche.nixplay.FragMent.NixPlayFragment
import com.airiche.nixplay.FragMent.PhotoFragment
import com.airiche.nixplay.R
import com.airiche.nixplay.Utils.StatusBarutrl
import kotlinx.android.synthetic.main.activity_main_interface.*


class MainInterfaceActivity : FragmentActivity() {
    private var mfragmentManager: FragmentManager? = null

    //创建的四个碎片
    private var mNixPlayFragment: NixPlayFragment? = null
    private var mPhotoFragment: PhotoFragment? = null
    private var mFriendsFragment: FriendsFragment? = null
    private var mMoreFragment: MoreFragment? = null

    private var TAG: String = "MainInterfaceActivity"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main_interface)
 
        Initialization()
    }


    private fun Initialization() {
        mfragmentManager = getSupportFragmentManager();  //获得FragmentManager的对象
        setTabSelection(0)

        //这是这个activity的点击事件 四个button
        NixPlayButton.setOnClickListener {
            setTabSelection(0)
        }
        PhotoButton.setOnClickListener {
            setTabSelection(1)
        }
        FriendButton.setOnClickListener {
            setTabSelection(2)
        }
        MoreButton.setOnClickListener {
            setTabSelection(3)
        }
    }



    /**
     * 根据传入的index参数来设置选中的tab页。
     * @param index
     * 每个tab页对应的下标。
     **/
    private fun setTabSelection(index: Int) {
        Log.e(TAG, "index===" + index)
        CleanImageState()
        var mFragmentTransaction = mfragmentManager!!.beginTransaction()
        // 每次选中之前先清楚掉上次的选中状态
        hideAllFragment(mFragmentTransaction)
        when (index) {
            0 -> {
                NixPlayButton.setImageResource(R.drawable.nixplay)
                if (null == mNixPlayFragment) {
                    mNixPlayFragment = NixPlayFragment()
                    mFragmentTransaction!!.add(R.id.InterFace_FrameLayout, mNixPlayFragment!!)
                } else {
                    mFragmentTransaction!!.show(mNixPlayFragment!!)
                }
            }
            1 -> {
                PhotoButton.setImageResource(R.drawable.photo)
                if (null == mPhotoFragment) {
                    mPhotoFragment = PhotoFragment()
                    mFragmentTransaction!!.add(R.id.InterFace_FrameLayout, mPhotoFragment!!)
                } else {
                    mFragmentTransaction!!.show(mPhotoFragment!!)
                }
            }
            2 -> {
                FriendButton.setImageResource(R.drawable.friend)
                if (null == mFriendsFragment) {
                    mFriendsFragment = FriendsFragment()
                    mFragmentTransaction!!.add(R.id.InterFace_FrameLayout, mFriendsFragment!!)
                } else {
                    mFragmentTransaction!!.show(mFriendsFragment!!)
                }
            }
            3 -> {
                MoreButton.setImageResource(R.drawable.more)
                if (null == mMoreFragment) {
                    mMoreFragment = MoreFragment()
                    mFragmentTransaction!!.add(R.id.InterFace_FrameLayout, mMoreFragment!!)
                } else {
                    mFragmentTransaction!!.show(mMoreFragment!!)
                }
            }
        }
        mFragmentTransaction!!.commit();  //提交
    }

    /**
     * 将所有的Fragment都置为隐藏状态。
     * @param transaction
     * 用于对Fragment执行操作的事务
     */
    private fun hideAllFragment(mFragmentTransaction: FragmentTransaction) {
        if (null != mNixPlayFragment) {
            mFragmentTransaction!!.hide(mNixPlayFragment!!)
        }
        if (null != mPhotoFragment) {
            mFragmentTransaction!!.hide(mPhotoFragment!!)
        }
        if (null != mFriendsFragment) {
            mFragmentTransaction!!.hide(mFriendsFragment!!)
        }
        if (null != mMoreFragment) {
            mFragmentTransaction!!.hide(mMoreFragment!!)
        }
    }

    private fun CleanImageState() {
        //这是四个点击事件的背景图更改 你们视情况而定
        NixPlayButton.setImageResource(R.drawable.nixplay_box)
        PhotoButton.setImageResource(R.drawable.photo_box)
        FriendButton.setImageResource(R.drawable.friend_box)
        MoreButton.setImageResource(R.drawable.more_box)
    }
}

这就是些主要代码了,别的就不贴了,从android包到androidx,对应的TabLayout+Fragment+ViewPager也会有影响: 

注释:MainInterfaceActivity 这个activity主要内容就是Fragment,里面包含四个碎片,然后TabLayout在碎片PhotoFragment 里面,那么接下来我们就来看一下这个Fragment

接下来我们再来看下TabLayout+Fragment+ViewPager的操作:

首先导包:

implementation 'com.android.support:design:26.1.0'

 布局:布局当中主要有TabLayout以及ViewPager两个控件

<?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="match_parent" android:layout_height="match_parent"
              android:orientation="vertical"
              android:layout_marginTop="@dimen/x20"
              android:background="@color/MainInterFace_background">

    <com.google.android.material.tabs.TabLayout
            android:id="@+id/Pnoto_Table"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@null"/>

  

    <androidx.viewpager.widget.ViewPager
            android:id="@+id/Pnoto_vp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>


</LinearLayout>

接下来我们就看一下布局所对应的PhotoFragment碎片代码,这个碎片里面是主要的代码,里面Viewpager关联TabLayout,碎片关联ViewPager

package com.airiche.nixplay.FragMent

import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getColor
import androidx.core.view.setPadding
import androidx.fragment.app.Fragment
import com.airiche.nixplay.FragMent.Adpate.FramentManagerAdapter
import com.airiche.nixplay.MainApplication

import com.airiche.nixplay.R
import com.google.android.material.tabs.TabLayout
import kotlinx.android.synthetic.main.fragment_photo.view.*
import java.util.ArrayList


class PhotoFragment : Fragment() {
    private var mFramentManagerAdapter: FramentManagerAdapter? = null

    override fun onCreateView(inflater: LayoutInflater,
                              container: ViewGroup?, savedInstanceState: Bundle?): View? {
        var view = inflater.inflate(R.layout.fragment_photo, container, false)

        Initialization(view)
        return view
    }

    public fun Initialization(view: View){
        //这个适配器里面主要的是有两个碎片,所对应的TabLayout的两个标题
        mFramentManagerAdapter = FramentManagerAdapter(
            activity!!.getSupportFragmentManager() , activity!!
        )
        
        //存储两个标题 TabLayout的标题
        val strings = ArrayList<String>()
        strings.add("PLAYLISTS")
        strings.add("ALBUMS")

        mFramentManagerAdapter!!.setData(strings)
        //ViewPager
        view.Pnoto_vp.setAdapter(mFramentManagerAdapter)
        //这个地方就是关联Viewpager与TabLayout的关键 这个主要是滑动的时候去切换标题
        view.Pnoto_Table.setupWithViewPager(view.Pnoto_vp)
        //同时关联两个碎片 那么点击两个TabLayout的标题的时候切换碎片
        view.Pnoto_Table.setTabsFromPagerAdapter(mFramentManagerAdapter)
    }

}

接下来我们就看一下这个适配器FramentManagerAdapter:

package com.airiche.nixplay.FragMent.Adpate

import android.content.Context
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.airiche.nixplay.Adpate.CustomFragmentPagerAdapter
import com.airiche.nixplay.FragMent.fragment.PnotoAlbumsFragment
import com.airiche.nixplay.FragMent.fragment.PnotoPlaylistsFragment

/**
 * Created by yingmuliang on 2019/11/21.
 * 这个碎片主要是用作ViewPager
 */
class FramentManagerAdapter(fm: FragmentManager, context: Context) : CustomFragmentPagerAdapter<String>(fm, context) {

    override fun getItem(position: Int): Fragment {
        return if (position == 0) {
             //这是你的碎片对象之一 
            PnotoPlaylistsFragment.newInstance()
        } else {
             //这是你的碎片对象之一
            PnotoAlbumsFragment.newInstance()
        }
    }

    override fun getPageTitle(position: Int): CharSequence? {
        return getData(position)
    }


}

再来看一下这个公共的适配器CustomFragmentPagerAdapter,它继承FragmentPagerAdapter 这个适配器

package com.airiche.nixplay.Adpate;

import android.content.Context;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;


import java.util.ArrayList;
import java.util.List;

/**
 * Created by yingmuliang on 2019/11/21.
 */
public abstract class CustomFragmentPagerAdapter<T> extends FragmentPagerAdapter {

    protected final List<T> datas = new ArrayList<T>();
    protected final Context context;
    protected T data;

    public CustomFragmentPagerAdapter(FragmentManager fm, Context context) {
        super(fm);
        this.context = context;
    }

    @Override
    public int getCount() {
        return datas.size();
    }

    public T getData(int position) {
        return datas.get(position);
    }

    public void setData(List<T> data) {
        if (data != null && data.size() > 0) {
            datas.clear();
            datas.addAll(data);
            notifyDataSetChanged();
        }
    }

    public void clear() {
        datas.clear();
    }

    public void clearAndNotify() {
        datas.clear();
        notifyDataSetChanged();
    }

}

ViewPager所需的两个碎片,刚刚的适配器里面对应的两个碎片

package com.airiche.nixplay.FragMent.fragment

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

import com.airiche.nixplay.R

class PnotoAlbumsFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_pnoto_albums, container, false)
    }

    companion object {
        fun newInstance(): PnotoAlbumsFragment {
            val args = Bundle()
            val fragment = PnotoAlbumsFragment()
            fragment.setArguments(args)
            return fragment
        }
    }
}

 

package com.airiche.nixplay.FragMent.fragment


import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.airiche.nixplay.Activity.MainInterfaceActivity
import com.airiche.nixplay.MainApplication

import com.airiche.nixplay.R

class PnotoPlaylistsFragment : Fragment() {


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_pnoto_playlists, container, false)
    }

    companion object {
        fun newInstance(): PnotoPlaylistsFragment {
            val args = Bundle()
            val fragment = PnotoPlaylistsFragment()
            fragment.setArguments(args)
            return fragment
        }
    }

}

这两碎片布局我就懒得上布局了!,上面基本就把代码介绍完了!

扩展:TableLayout中线条改变,以及文字改变

我们先来改变线条,通过查找api我没找到有直接设置代码设置的,但是我找到个神奇的东西,先在Tablelayout的布局中设置

app:tabIndicatorHeight="0dp"

 再创建一个tab_selector.xml样式:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/tab_selected" android:state_selected="true" />
    <item android:drawable="@color/design_fab_shadow_end_color" />
</selector>
tab_selected.xml:
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 整个背景色-->
    <item>
        <shape>
            <solid android:color="@color/design_fab_shadow_end_color" />
        </shape>
    </item>
    <!-- 底部圆角,参数是固定的 -->
    <item
            android:width="100dp"
            android:height="2dp"
            android:gravity="bottom|center_horizontal">
        <shape>
            <solid android:color="@color/photo_table_color" />/>
        </shape>
    </item>
</layer-list>

使用:

app:tabBackground="@drawable/tab_selector"

整体布局:

  <com.google.android.material.tabs.TabLayout
            android:id="@+id/Pnoto_Table"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@null"
            app:tabIndicatorHeight="0dp"
            app:tabBackground="@drawable/tab_selector"/>

 这就是那根标签线的设置了,我们再来看标签文字的设置:

它有两种状态,选中以及未选中:直接上代码吧,不墨迹了:

    <com.google.android.material.tabs.TabLayout
            android:id="@+id/Pnoto_Table"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@null"
            app:tabIndicatorHeight="0dp"
            app:tabBackground="@drawable/tab_selector"
            app:tabSelectedTextColor="@color/Table_enble_TextColor" 
            app:tabTextColor="@color/tabTextColor"/>

 app:tabSelectedTextColor="@color/Table_enble_TextColor" //选中颜色
 app:tabTextColor="@color/tabTextColor"  //未选中颜色

//扩展: 去掉点击阴影app:tabRippleColor = "@android:color/transparent" 或者你设置成自己想要的点击颜色

 

emmmmm.....大概就这么些了,有什么问题直接找我就好了,邮箱地址:1627000323@qq.com 

 


版权声明:本文为qq_36333309原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。