web-dev-qa-db-ja.com

次/前のカードRecyclerViewの一部を表示する方法

この機能を実現するための最良の戦略は何ですか?

enter image description here

カードが付いた横向きのRecyclerViewがあります。各カードは画面全体に表示されますが、アイテムが複数ある場合は、次のカードと前のカードの一部を表示したいと思います。

アダプタでカードAndroid:layout_widthmatch_parentではなく250dpのような特定のDPに設定することで、これを実現できることはわかっています。しかし、それは適切な解決策のようには見えません。

これは私のコードです:

RecyclerViewでのアクティビティ:

    class ListPokemon : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val items = createListPokemons()
        recyclerView.adapter = PokemonAdapter(items)
        recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
        recyclerView.setHasFixedSize(true)
        val pagerSnapHelper = PagerSnapHelper()
        pagerSnapHelper.attachToRecyclerView(recyclerView)
    }

    private fun createListPokemons(): List<Pokemon> {
        val pokemons = ArrayList<Pokemon>()
        pokemons += createPokemon("Pikachu")
        pokemons += createPokemon("Bulbasaur")
        pokemons += createPokemon("Charmander")
        pokemons += createPokemon("Squirtle")

        return pokemons
    }

    private fun createPokemon(name: String) = Pokemon(name = name, height = 1, weight = 69, id = 1)
}

アクティビティのレイアウト:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.constraint.ConstraintLayout
    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:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Android.support.v7.widget.RecyclerView
        Android:id="@+id/recyclerView"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:layoutManager="Android.support.v7.widget.LinearLayoutManager"/>

</Android.support.constraint.ConstraintLayout>

アダプタ:

class PokemonAdapter(val list: List<Pokemon>) : RecyclerView.Adapter<PokemonAdapter.PokemonVH>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PokemonAdapter.PokemonVH {
        return PokemonVH(LayoutInflater.from(parent.context)
            .inflate(R.layout.pokemon_item, parent, false))
    }

    override fun onBindViewHolder(holder: PokemonAdapter.PokemonVH, position: Int) {
        holder.textViewName.text = list[position].name
    }

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

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

        var textViewName: TextView = itemView.findViewById(R.id.textViewName)
    }
}

アダプターのレイアウト:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.CardView
    Android:layout_gravity="center_horizontal"
    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:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_marginStart="16dp"
    Android:layout_marginEnd="16dp"
    app:cardCornerRadius="8dp"
    app:cardElevation="4dp">

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical">

        <TextView
            Android:padding="36dp"
            Android:id="@+id/textViewName"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:gravity="center"
            Android:textSize="22sp"
            tools:text="Teste String"/>

    </LinearLayout>

</Android.support.v7.widget.CardView>

これは私の結果です:

enter image description here

この状況で次のカードの一部を紹介したいと思います。これどうやってするの?

ありがとう。

14
leonvian

あなたがする必要があるのは、RecyclerViewにパディングを設定し、clipToPaddingfalseに設定し、SnapHelperを使用して、そしてカードのマージンがRecylerViewのパディング以下です。

したがって、カードから画面の端までの距離を16 dpにして、カード間の距離を8 dpにしたいとします。各カードのマージンを4 dpに設定する必要があるため、合計マージンは8 dpになります。また、カードの両側にすでに4 dpのマージンがあるため、パディングを12 dpに設定する必要があります。

次のようになります。

あなたのリスト:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.RecyclerView
    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="wrap_content"
    app:layoutManager="Android.support.v7.widget.LinearLayoutManager"
    Android:clipToPadding="false"
    Android:orientation="horizontal"
    Android:paddingStart="12dp"
    Android:paddingEnd="12dp"/>

あなたのカード:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.CardView
    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="wrap_content"
    Android:layout_marginEnd="4dp"
    Android:layout_marginStart="4dp"
    app:cardElevation="2dp"/>

最後のアイテムに強制的にパディングを付けるため、パディングソリューションはすべてのケースに適しているわけではないと思います。

個人的には、各項目のランタイム幅の計算を使用しており、これに非常に満足しています。したがって、次のことができます。

onBindViewHolder

if (position == data.size - 1) {
    holder.itemView.layoutParams = RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT)
} else {
    if (width == null) {
        holder.itemView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
              override fun onGlobalLayout() {
                   holder.itemView.viewTreeObserver.removeOnGlobalLayoutListener(this)
                   width = holder.itemView.width
                   params.width = width!! - partOfPage
                   holder.itemView.requestLayout()
              }
         })
     } else {
         params.width = width!! - partOfPage
         holder.itemView.requestLayout()
     }
 }

その結果、すべての中央のアイテムは次のページの一部を表示してレンダリングされますが、最後のアイテムは全幅でレンダリングされます。

1
mspapant

CardViewの幅を"match_parent"から"0dp"に変更します。そして、layout_weight"80"(または類似)として追加します。親ビュー(RecyclerViewlayout_weightSum"100"として作成します。

Android:layout_width="0dp"
Android:layout_weight="80"
0
Gokul Nath KP