将回收的视图卡片放在底部 Sheet
Keep Recycled View Cards within Bottom Sheet
我正在尝试在底部 sheet 中放入卡片。我已经尝试了所有方法,但我无法弄清楚如何在底部 sheet 中正确显示所有卡片。我的代码出现了多个底部 sheet 正在创建和卡片(见第二张照片)任何帮助将不胜感激。我正在尝试做类似于图示的事情,或者如果有任何资源可以复制它,因为我在任何地方都找不到与此类似的东西:
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (supportActionBar != null)
supportActionBar?.hide()
configureBackdrop()
val bottomSheetFragment = BottomSheetExampleDialogFragment()
bottomSheetFragment.show(supportFragmentManager, bottomSheetFragment.getTag())
}
private var mBottomSheetBehavior: BottomSheetBehavior<View?>? = null
private fun configureBackdrop() {
// Get the fragment reference
val fragment = supportFragmentManager.findFragmentById(R.id.filter_fragment)
fragment?.let {
// Get the BottomSheetBehavior from the fragment view
it.view?.let { it1 ->
BottomSheetBehavior.from(it1).let { bsb ->
mBottomSheetBehavior = bsb
}
}
}
}
}
CustomAdapter.kt
class CustomAdapter(val modelList: List<Model>, val context: Context) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder as ViewHolder).bind(modelList.get(position));
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return ViewHolder(layoutInflater.inflate(R.layout.backdrop_fragment, parent, false))
}
override fun getItemCount(): Int {
return modelList.size;
}
lateinit var mClickListener: ClickListener
fun setOnItemClickListener(aClickListener: ClickListener) {
mClickListener = aClickListener
}
interface ClickListener {
fun onClick(pos: Int, aView: View)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
init {
itemView.setOnClickListener(this)
}
override fun onClick(p0: View?) {
mClickListener.onClick(adapterPosition, itemView)
}
fun bind(model: Model): Unit {
itemView.txt.text = model.name
itemView.sub_txt.text = model.version
val id = context.resources.getIdentifier(model.name.toLowerCase(Locale.ROOT), "drawable", context.packageName)
itemView.img.setBackgroundResource(id)
}
}
}
BottomSheetDialogueFragment.kt
class BottomSheetExampleDialogFragment : BottomSheetDialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) : View? =
inflater.inflate(R.layout.bottom_sheet_layout, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Handle RecyclerView here
val modelList = readFromAsset()
val adapter = context?.let { CustomAdapter(modelList, it) }
rcv.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
rcv.adapter = adapter;
}
private fun readFromAsset(): List<Model> {
val modeList = mutableListOf<Model>()
val bufferReader = context?.assets?.open("android_version.json")?.bufferedReader()
val json_string = bufferReader.use {
it?.readText()
}
val jsonArray = JSONArray(json_string);
for (i in 0..jsonArray.length() - 1) {
val jsonObject: JSONObject = jsonArray.getJSONObject(i)
val model = Model(jsonObject.getString("name"), jsonObject.getString("version"))
modeList.add(model)
}
return modeList
}
}
BackdropFragment.kt
class BackdropFragment: Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.backdrop_fragment, container, false)
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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">
<TextView
android:id="@+id/textView"
android:text="@string/main_activity_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<fragment
app:behavior_hideable="false"
app:behavior_peekHeight="10dp"
android:layout_marginTop="?attr/actionBarSize"
app:behavior_skipCollapsed="false"
android:id="@+id/filter_fragment"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:name="behavior.sheet.bottom.BackdropFragment" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
backdrop_fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/backdrop_fragment_background"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/backdrop_content" />
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="75dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical"
card_view:cardCornerRadius="30dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="false"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
card_view:contentPadding="10dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:text="Title"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/img"
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_marginStart="25dp"
android:layout_toRightOf="@+id/txt"
android:contentDescription="@string/app_name" />
<TextView
android:id="@+id/sub_txt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="25dp"
android:layout_toRightOf="@+id/img"
android:autoSizeMaxTextSize="8sp"
android:autoSizeMinTextSize="6sp"
android:autoSizeStepGranularity="2sp"
android:autoSizeTextType="uniform"
android:text="Title" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
bottom_sheet_layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rcv"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
使用您想要的任何约束自定义布局并通过 Recycler View 的布局行为,只需将 View 替换为 RecyclerView。
app:layout_behavior="app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior""
在 class 文件中使用
使用全局变量
private var mBottomSheetBehavior: BottomSheetBehavior<*>? = null
在视图中创建了设置布局管理器和适配器。
mBottomSheetBehavior = BottomSheetBehavior.from(view);
mBottomSheetBehavior?.peekHeight = 0
setBottomSheetAndCallBackBottomSheetBehaviour();
bottomSheetCollapsed();
bottomSheet?.visibility = View.VISIBLE
并且在创建名为方法的视图并传递布局 ID 时,窥视高度用于第一次隐藏视图。
/**
* set bottom sheet behavior and state
*/
private fun setBottomSheetAndCallBackBottomSheetBehaviour() {
mBottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN
//callback
mBottomSheetBehavior?.setBottomSheetCallback(object :
BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
bottomSheetCollapsed()
}
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {}
})
}
并使用以下方法进行展开和折叠。
private fun bottomSheetExpand() {
mBottomSheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
}
private fun bottomSheetCollapsed() {
mBottomSheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
}
点击查看使用
fun isExpendCollapse(){
if (mBottomSheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) {
bottomSheetExpand()
} else {
bottomSheetCollapsed()
}
}
检查 xml 文件 CoordinatorLayout 是 bottomsheet 行为所必需的
<android.support.design.widget.CoordinatorLayout
android:id="@+id/bottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:clipToPadding="true"
android:visibility="gone"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
android:layout_alignParentBottom="true"
>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerr_view"
android:layout_width="match_parent"
android:layout_height="300dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
/>
</android.support.design.widget.CoordinatorLayout>
您可以约束布局、线性或任何视图而不是视图。并且我已经使用相对布局(父布局)设置坐标布局,您可以根据需要使用。
我正在尝试在底部 sheet 中放入卡片。我已经尝试了所有方法,但我无法弄清楚如何在底部 sheet 中正确显示所有卡片。我的代码出现了多个底部 sheet 正在创建和卡片(见第二张照片)任何帮助将不胜感激。我正在尝试做类似于图示的事情,或者如果有任何资源可以复制它,因为我在任何地方都找不到与此类似的东西:
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (supportActionBar != null)
supportActionBar?.hide()
configureBackdrop()
val bottomSheetFragment = BottomSheetExampleDialogFragment()
bottomSheetFragment.show(supportFragmentManager, bottomSheetFragment.getTag())
}
private var mBottomSheetBehavior: BottomSheetBehavior<View?>? = null
private fun configureBackdrop() {
// Get the fragment reference
val fragment = supportFragmentManager.findFragmentById(R.id.filter_fragment)
fragment?.let {
// Get the BottomSheetBehavior from the fragment view
it.view?.let { it1 ->
BottomSheetBehavior.from(it1).let { bsb ->
mBottomSheetBehavior = bsb
}
}
}
}
}
CustomAdapter.kt
class CustomAdapter(val modelList: List<Model>, val context: Context) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder as ViewHolder).bind(modelList.get(position));
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return ViewHolder(layoutInflater.inflate(R.layout.backdrop_fragment, parent, false))
}
override fun getItemCount(): Int {
return modelList.size;
}
lateinit var mClickListener: ClickListener
fun setOnItemClickListener(aClickListener: ClickListener) {
mClickListener = aClickListener
}
interface ClickListener {
fun onClick(pos: Int, aView: View)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
init {
itemView.setOnClickListener(this)
}
override fun onClick(p0: View?) {
mClickListener.onClick(adapterPosition, itemView)
}
fun bind(model: Model): Unit {
itemView.txt.text = model.name
itemView.sub_txt.text = model.version
val id = context.resources.getIdentifier(model.name.toLowerCase(Locale.ROOT), "drawable", context.packageName)
itemView.img.setBackgroundResource(id)
}
}
}
BottomSheetDialogueFragment.kt
class BottomSheetExampleDialogFragment : BottomSheetDialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) : View? =
inflater.inflate(R.layout.bottom_sheet_layout, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Handle RecyclerView here
val modelList = readFromAsset()
val adapter = context?.let { CustomAdapter(modelList, it) }
rcv.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
rcv.adapter = adapter;
}
private fun readFromAsset(): List<Model> {
val modeList = mutableListOf<Model>()
val bufferReader = context?.assets?.open("android_version.json")?.bufferedReader()
val json_string = bufferReader.use {
it?.readText()
}
val jsonArray = JSONArray(json_string);
for (i in 0..jsonArray.length() - 1) {
val jsonObject: JSONObject = jsonArray.getJSONObject(i)
val model = Model(jsonObject.getString("name"), jsonObject.getString("version"))
modeList.add(model)
}
return modeList
}
}
BackdropFragment.kt
class BackdropFragment: Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.backdrop_fragment, container, false)
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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">
<TextView
android:id="@+id/textView"
android:text="@string/main_activity_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<fragment
app:behavior_hideable="false"
app:behavior_peekHeight="10dp"
android:layout_marginTop="?attr/actionBarSize"
app:behavior_skipCollapsed="false"
android:id="@+id/filter_fragment"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:name="behavior.sheet.bottom.BackdropFragment" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
backdrop_fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/backdrop_fragment_background"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/backdrop_content" />
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="75dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical"
card_view:cardCornerRadius="30dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="false"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
card_view:contentPadding="10dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:text="Title"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/img"
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_marginStart="25dp"
android:layout_toRightOf="@+id/txt"
android:contentDescription="@string/app_name" />
<TextView
android:id="@+id/sub_txt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="25dp"
android:layout_toRightOf="@+id/img"
android:autoSizeMaxTextSize="8sp"
android:autoSizeMinTextSize="6sp"
android:autoSizeStepGranularity="2sp"
android:autoSizeTextType="uniform"
android:text="Title" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
bottom_sheet_layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rcv"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
使用您想要的任何约束自定义布局并通过 Recycler View 的布局行为,只需将 View 替换为 RecyclerView。
app:layout_behavior="app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior""
在 class 文件中使用
使用全局变量
private var mBottomSheetBehavior: BottomSheetBehavior<*>? = null
在视图中创建了设置布局管理器和适配器。
mBottomSheetBehavior = BottomSheetBehavior.from(view);
mBottomSheetBehavior?.peekHeight = 0
setBottomSheetAndCallBackBottomSheetBehaviour();
bottomSheetCollapsed();
bottomSheet?.visibility = View.VISIBLE
并且在创建名为方法的视图并传递布局 ID 时,窥视高度用于第一次隐藏视图。
/**
* set bottom sheet behavior and state
*/
private fun setBottomSheetAndCallBackBottomSheetBehaviour() {
mBottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN
//callback
mBottomSheetBehavior?.setBottomSheetCallback(object :
BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
bottomSheetCollapsed()
}
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {}
})
}
并使用以下方法进行展开和折叠。
private fun bottomSheetExpand() {
mBottomSheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
}
private fun bottomSheetCollapsed() {
mBottomSheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
}
点击查看使用
fun isExpendCollapse(){
if (mBottomSheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) {
bottomSheetExpand()
} else {
bottomSheetCollapsed()
}
}
检查 xml 文件 CoordinatorLayout 是 bottomsheet 行为所必需的
<android.support.design.widget.CoordinatorLayout
android:id="@+id/bottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:clipToPadding="true"
android:visibility="gone"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
android:layout_alignParentBottom="true"
>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerr_view"
android:layout_width="match_parent"
android:layout_height="300dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
/>
</android.support.design.widget.CoordinatorLayout>
您可以约束布局、线性或任何视图而不是视图。并且我已经使用相对布局(父布局)设置坐标布局,您可以根据需要使用。