Android 小控件

一、Fragment

1.简单使用

//test_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#00ff00"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:textSize="24sp"
        android:text="This is right fragment"
        />
</LinearLayout>

//main.xml
<fragment
	android:id="@+id/leftFrag"
	android:name="com.example.fragmenttest.LeftFragment"
	android:layout_width="0dp"
	android:layout_height="match_parent"
	android:layout_weight="1" />

//Fragment可实例化的类
class LeftFragment : Fragment() {
	override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
		savedInstanceState: Bundle?): View? {
		return inflater.inflate(R.layout.test_fragment, container, false)
	}
}

2.动态添加

<FrameLayout
	android:id="@+id/rightLayout"
	android:layout_width="0dp"
	android:layout_height="match_parent"
	android:layout_weight="1" >
</FrameLayout>

fun addFragment(fragment:Fragment) {
	val fragmentManager = getSupportFragmentManager()//获取fragmentManager实例
	val transaction = fragmentManager.beginTransaction()//创建事务
	transaction.replace(R.id.rightLayout,fragment)//替换fragment,需要先创建fragment实例
	transaction.addToBackStack(null)//将事务添加到返回栈
	tracsaction.commit()//提交事务
}

二、ViewPager2

androidx.viewpager2.widget.ViewPager2
以滑动的方式显示view或fragment,ViewPager2通过Adapter显示Views或Fragments。
Adapter类继承FragmentStateAdapter,感知各个页面的变化。

//activity
val vp2 = findViewById<View>(R.id.vp2) as ViewPager2
val fragments = mutableListOf(Fragment1(), Fragment2())
val adapter = MyAdapter(this, fragments as ArrayList<Fragment>)
vp2.adapter = adapter
vp2.orientation = ViewPager2.ORIENTATION_VERTICAL//设置滑动方式为垂直方向
//Adapter
class MyAdapter(fragmentActivity: FragmentActivity, private val fragments: ArrayList<Fragment>) : FragmentStateAdapter(fragmentActivity) {
    override fun createFragment(position: Int): Fragment {
        return fragments[position]
    }
    override fun getItemCount():Int {
        return fragments.size
    }
}
//Fragment
class Fragment1 : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val tv = TextView(context)
        tv.text = "第一页"
        tv.setBackgroundColor(Color.parseColor("#f7acbc"))
        tv.gravity = Gravity.CENTER
        return tv
    }
}
class Fragment2 : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val tv = TextView(context)
        tv.text = "第二页"
        tv.setBackgroundColor(Color.parseColor("#11a2bc"))
        tv.gravity = Gravity.CENTER
        return tv
    }
}
//build.gradle
implementation "androidx.viewpager2:viewpager2:1.0.0"

2.RecylerView

androidx.recyclerview.widget.RecyclerView
RecylerView可通过Adapter和ViewHolder进行显示,类似于表格显示。
Adapter和ViewHolder类都需要继承RecylerView.Adapter和RecylerView.ViewHolder

//activity
val listData = mutableListOf<TestData>(
    TestData("北京市"),
    TestData("上海市"),
    TestData("广州市"),
    TestData("深圳市"),
    TestData("杭州市"),
    TestData("南京市"),
    TestData("成都市"),
    TestData("重庆市"),
    TestData("西安市"),
    TestData("天津市"),
    TestData("苏州市"),
)
var listTestData = TestAdapter {
    Log.d("选择的项:","$it")//最后响应
}.apply {
    data = listData
}
binding.recylerView.layoutManager = LinearLayoutManager(this)
binding.recylerView.adapter = listTestData
//adapter
class TestAdapter(private var adapterListener: (testData: TestData) -> Unit) :
    RecyclerView.Adapter<TestViewHolder>() {

    var data = mutableListOf<TestData>()
        set(value) {
            if (value.isNotEmpty()) {
                field.addAll(value)
            }
        }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestViewHolder {
        val binding = ViewFormBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return TestViewHolder(binding)
    }

    override fun getItemCount(): Int {
        return data.size
    }

    override fun onBindViewHolder(holder: TestViewHolder, position: Int) {
        holder.bind(data[position]) {
            data.forEach {
                it.isSelected = false
            }
            data[position].isSelected = true
            notifyDataSetChanged()
            adapterListener.invoke(data[position])//其次响应
        }
    }
}
//viewHodler
class TestViewHolder(private val binding: ViewFormBinding) :
    RecyclerView.ViewHolder(binding.root) {

    fun bind(testData: TestData, ViewListener: (testData: TestData) -> Unit) {
        binding.contentTv.text = testData.name
        var color = if (testData.isSelected) {
            Color.parseColor("#495CCE")
        } else {
            Color.parseColor("#666666")
        }
        binding.contentTv.setTextColor(color)
        itemView.setOnClickListener {//首先响应
            ViewListener.invoke(testData)
        }
    }
}
//data
data class TestData(
    var name:String,
    var isSelected:Boolean = false
)
//build.gradle
viewBinding {
   enabled = true
}

3.LinearLayoutCompat

androidx.appcompat.widget.LinearLayoutCompat
默认水平布局;divider属性必须在drawable目录下定义相关xml文件,定义水平或垂直间隔中间隔线的颜色属性和长度或宽度属性

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#f22222" />
    <size android:height="0.8dp" />
</shape>

style属性可通过values目录下定义文件设置风格属性

//layout,该布局内的控件均按默认水平排列
<androidx.appcompat.widget.LinearLayoutCompat
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:divider="@drawable/divider_item"//各个LinearLayoutCompat之间的分割线样式
    app:showDividers="middle|beginning">
    <androidx.appcompat.widget.LinearLayoutCompat
    //没有设置orientation则默认为水平
		style="@style/ll_menu_item_style"
		android:layout_width="match_parent">
		<Button
			.../>
		<Button
			.../>
	</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
//style.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="ll_menu_item_style">
        <item name="android:layout_height">wrap_content</item>
        <item name="android:minHeight">60dp</item>
        <item name="android:paddingTop">5dp</item>
        <item name="android:paddingBottom">5dp</item>
        <item name="android:paddingStart">16dp</item>
        <item name="android:gravity">center_vertical</item>
        <item name="android:paddingEnd">16dp</item>
    </style>
</resources>

LinearLayout控件相比LinearLayoutCompat没有自动设置间隔线的操作,需要用view来设置每个间隔线。

4.RadioGroup

单选按钮,为单选按钮组设置监听器

RadioGroup radGroup = (RadioGroup) findViewById(R.id.radioGroup);
//为radioGroup设置一个监听器:setOnCheckedChanged()  
radGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        RadioButton radBtn = (RadioButton) findViewById(checkedId);
        Toast.makeText(getApplicationContext(), "按钮组值发生改变,你选了" + radBtn .getText(), Toast.LENGTH_LONG).show();
    }
});

5.ChecBox复选框

6.Navigation

(1)build.gradle依赖:

dependencies {
	val nav_version = "2.5.3"
	implementation("androidx.navigation:navigation-fragment-ktx:$nav_version")
  	implementation("androidx.navigation:navigation-ui-ktx:$nav_version")
}

(2)创建:在res目录下New > Android Resource File,增加resource type为navigation

在这里插入图片描述

(3)向activity添加NavHost

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"//固定写法
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"

    app:defaultNavHost="true"//确保NavHostFragment拦截系统返回按钮。只能有一个默认 NavHost。如果同一布局(例如,双窗格布局)中有多个宿主,请务必仅指定一个默认 NavHost
    app:navGraph="@navigation/nav_graph" />//与导航图相关联

(4)在navigation在配置Fragment

<navigation 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/fragmentA">//初始显示页面

    <fragment
        android:id="@+id/fragmentA"
        android:name="com.example.navi.FragmentA"
        android:label="fragment_a"
        tools:layout="@layout/fragment_a" >
        <action
            android:id="@+id/action_fragmentA_to_fragmentB"
            app:destination="@id/fragmentB" />
    </fragment>
    <fragment
        android:id="@+id/fragmentB"
        android:name="com.example.navi.FragmentB"
        android:label="fragment_b"
        tools:layout="@layout/fragment_b" >
        <action
            android:id="@+id/action_fragmentB_to_fragmentC"
            app:destination="@id/fragmentC" />
    </fragment>
    <fragment
        android:id="@+id/fragmentC"
        android:name="com.example.navi.FragmentC"
        android:label="fragment_c"
        tools:layout="@layout/fragment_c" />
</navigation>

(5)创建单个布局文件

(6)fragment跳转

class FragmentA : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_a, container, false)
        view.findViewById<Button>(R.id.button).setOnClickListener {
            findNavController().navigate(R.id.action_fragmentA_to_fragmentB)
        }
        return view
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值