更新数据时,RecyclerView会更改项目高度

时间:2018-03-22 16:37:56

标签: android android-recyclerview kotlin

我使用SearchViewRecyclerView制作应用。要更新结果,请使用DiffUtil。更新数据时,某些项目会更改其高度,但如果我关闭软键盘,则它们将是正常大小。如果我使用notifyDataSetChanged()它们不会改变它们的高度,但我需要一个动画。

这是我的my_item.xml

<carbon.widget.RelativeLayout 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"
    style="@style/carbon_CardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:focusable="true"
    android:layout_margin="0dp"
    android:padding="0dp"
    app:carbon_elevation="4dp"
    app:carbon_rippleColor="@color/dust"
    app:carbon_rippleStyle="over">

    <ImageView
        android:id="@+id/my_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true" />

    <carbon.widget.RelativeLayout
        android:id="@+id/my_info_wrapper"
        android:layout_below="@+id/my_image"
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/snow"
        android:paddingBottom="8dp"
        android:paddingLeft="16dp"
        android:paddingRight="8dp"
        android:paddingStart="16dp"
        android:paddingEnd="8dp"
        android:paddingTop="8dp"
        android:layout_margin="0dp">

        <carbon.widget.ImageView
            android:id="@+id/my_second_image"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_centerInParent="true"
            android:layout_gravity="center"
            android:layout_marginLeft="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginBottom="0dp" />

        <carbon.widget.TextView
            android:id="@+id/my_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@id/my_second_image"
            android:layout_toStartOf="@id/my_second_image"
            android:gravity="start"
            android:singleLine="true"
            android:textColor="@color/stone_dark"
            android:textSize="14sp"
            android:layout_margin="0dp"
            app:carbon_fontPath="Roboto-Medium.ttf" />

        <carbon.widget.TextView
            android:id="@+id/my_subtitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/my_title"
            android:layout_toLeftOf="@id/my_second_image"
            android:layout_toStartOf="@id/my_second_image"
            android:gravity="start"
            android:singleLine="true"
            android:textColor="@color/stone_normal"
            android:textSize="12sp"
            android:layout_margin="0dp"
            app:carbon_fontPath="Roboto-Regular.ttf" />
    </carbon.widget.RelativeLayout>
</carbon.widget.RelativeLayout>

MyAdapter.kt

class MyAdapter (private val clickListener: (Int) -> Unit) :
        RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    var items: List<MyListItem> = listOf()

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

    override fun onBindViewHolder(holder: MyAdapter.MyViewHolder, position: Int) {
        holder.bind(items[position], clickListener)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter.MyViewHolder {
        return MyViewHolder(LayoutInflater.from(parent.context)
                .inflate(R.layout.my_item, parent, false))
    }

    class RockViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun bind(item: RockListItem, clickListener: (Int) -> Unit) {
            itemView.setOnClickListener {
                clickListener.invoke(item.id)
            }
            itemView.my_title.text = item.title
            Picasso.with(itemView.context)
                    .load(item.second_image)
                    .into(itemView.my_second_image)
            val identifier = itemView.context.resources
                    .getIdentifier(item.picName, "drawable", itemView.context.packageName)
            Picasso.with(itemView.context)
                    .load(identifier)
                    .fit()
                    .into(itemView.my_image)
            itemView.my_subtitle.text = ""
        }

    }

}

这是MyFragment.kt

class RockListFragment : Fragment() {

    private lateinit var listViewModel: MyViewModel
        private val adapter: RockListAdapter = MyAdapter({ itemId ->
            openDetail(itemId)
        })
        private var itemDecoration: GridSpacingItemDecoration? = null

        private lateinit var search: SearchView

        override fun onAttach(context: Context?) {
            super.onAttach(context)
            listViewModel = getViewModel()
            listViewModel.setItems("")
        }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            setHasOptionsMenu(true)
            val layoutManager = GridLayoutManager(activity, resources.getInteger(R.integer.grid_columns))
            recycler.layoutManager = layoutManager
            recycler.adapter = adapter
            recycler.setHasFixedSize(true)
            itemDecoration = GridSpacingItemDecoration(resources.getInteger(R.integer.grid_columns),
                    resources.getDimensionPixelSize(R.dimen.list_spacing))
            recycler.addItemDecoration(itemDecoration)
            listViewModel.rocks.observe(this, Observer { items ->
                if (items != null) {
                    val diffUtilCallback = RockDiffUtilCallback(adapter.items, items)
                    val diffResult = DiffUtil.calculateDiff(diffUtilCallback, false)
                    adapter.items = items
                    diffResult.dispatchUpdatesTo(adapter)
                    search_empty_state.visibleOrGone = items.isEmpty()
                    recycler.visibility = View.VISIBLE
                }
            })
        }

    override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
            inflater?.inflate(R.menu.menu_search_activity, menu)
            search = menu?.findItem(R.id.action_search)?.actionView as SearchView
            addToCompositeDisposable(
                    RxSearchView.queryTextChanges(search)
                            .debounce(250, TimeUnit.MILLISECONDS)
                            .subscribe { p0 ->
                                listViewModel.setItems(p0.toString())
                            })
        }
    }
}

最后MyViewModel.kt

class MyViewModel : BaseViewModel() {

    val rocks: MutableLiveData<List<MyListItem>> = MutableLiveData()
    @Inject lateinit var useCase: MyUseCase

    fun setRocks(search: String) {
        addToCompositeDisposable(useCase.getRocksList(search)
                .flatMap { list ->
                    return@flatMap Observable.fromIterable(list)
                            .map(MyListItemMapper())
                            .toList()
                }
                .subscribe({ list ->
                    items.value = list
                }))
    }

}

enter image description here

0 个答案:

没有答案