【问题标题】:Hi, im new in android dev and have questions about implementation of button onclick in viewpager2嗨,我是 android dev 的新手,对 viewpager2 中按钮 onclick 的实现有疑问
【发布时间】:2020-12-02 11:49:50
【问题描述】:

在我的应用程序中,我使用了 viewpager2,用户可以在其中滑动并通过单击按钮是/否来回答问题,就像测验一样。我试图设置按钮 onclicklistener ,单击时当前页面上的按钮应更改颜色(是=绿色,否=红色)。问题是当我单击按钮时,有时它会改变颜色,有时则不会。如果不是,即使还没有点击后页中的按钮也会受到影响。如何确保只有当前页面中的按钮在单击时会改变颜色?我的代码中按钮 onclick 的实现是错误的还是什么?我检查了logcat,没有显示错误。

这是我的 MyViewPagerAdapter.java

    public class MyViewPagerAdapter extends RecyclerView.Adapter<MyViewPagerAdapter.MyViewHolder> {

Context context;

int[][] question_matrix = new int[][]{
        //Visual motor
        {R.string.q1,R.string.q1m},
        {R.string.q2,R.string.q2m},
        //Fine motor
        {R.string.q3,R.string.q3m},
        {R.string.q4,R.string.q4m},
        {R.string.q5,R.string.q5m},
        {R.string.q6,R.string.q6m},
        //body posture
        {R.string.q7,R.string.q7m},
        {R.string.q8,R.string.q8m},
        {R.string.q9,R.string.q9m},
        //shoulder stability
        {R.string.q10,R.string.q10m},
        {R.string.q11,R.string.q11m},
        {R.string.q12,R.string.q12m},
        {R.string.q13,R.string.q13m},
        //spatial perception
        {R.string.q14,R.string.q14m},
        {R.string.q15,R.string.q15m},
        //cross mid-line
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q16,R.string.q16m},
        {R.string.q17,R.string.q17m},
        {R.string.q18,R.string.q18m},
        //visual skill
        {R.string.q19,R.string.q19m},
        {R.string.q20,R.string.q20m},

};

public MyViewPagerAdapter(Context context) {
    this.context = context;
}



@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_page,parent,false));
}

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position)  {

    holder.eQuestion.setText(question_matrix[position][0]);
    holder.mQuestion.setText(question_matrix[position][1]);
    holder.yes.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            holder.yes.setBackgroundColor(Color.GREEN);
            holder.no.setBackgroundColor(Color.LTGRAY);
        }
    });
    holder.no.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            holder.yes.setBackgroundColor(Color.LTGRAY);
            holder.no.setBackgroundColor(Color.RED);
        }
    });



}

@Override
public int getItemCount() {
    return question_matrix.length;
}



public class MyViewHolder extends RecyclerView.ViewHolder {


    TextView eQuestion,mQuestion;
    ConstraintLayout container;
    Button yes,no;
    ImageView img;

    public MyViewHolder(@NonNull View itemView) {
        super(itemView);
        img = itemView.findViewById(R.id.image_desc);
        eQuestion = itemView.findViewById(R.id.eQuestion);
        mQuestion = itemView.findViewById(R.id.mQuestion);
        container = itemView.findViewById(R.id.container);
        yes = itemView.findViewById(R.id.yesBtn);
        no = itemView.findViewById(R.id.noBtn);


    }


}


   }

  

这是我的 item_page.xml 的布局:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.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:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<ImageView
    android:id="@+id/image_desc"
    android:layout_width="300dp"
    android:layout_height="200dp"
    android:layout_centerHorizontal="true"
    android:src="@drawable/ic_q1"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.495"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.152" />

<TextView
    android:id="@+id/eQuestion"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/image_desc"
    android:layout_gravity="center"
    android:layout_marginStart="16dp"
    android:layout_marginEnd="16dp"
    android:text="question"
    android:textAlignment="center"
    android:textColor="@color/black"
    android:textSize="18sp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/image_desc"
    app:layout_constraintVertical_bias="0.108" />

<TextView
    android:id="@+id/mQuestion"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/eQuestion"
    android:layout_marginStart="16dp"
    android:layout_marginEnd="16dp"
    android:text="translation"
    android:textAlignment="center"
    android:textColor="#3A3939"
    android:textSize="15sp"
    android:textStyle="italic"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="1.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/eQuestion"
    app:layout_constraintVertical_bias="0.061" />

<Button
    android:id="@+id/noBtn"
    android:layout_width="170dp"
    android:layout_height="47dp"
    android:layout_marginStart="16dp"
    android:text="No"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.004"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/mQuestion"
    app:layout_constraintVertical_bias="0.69" />

<Button
    android:id="@+id/yesBtn"
    android:layout_width="170dp"
    android:layout_height="47dp"
    android:layout_marginEnd="16dp"
    android:text="Yes"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="1.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/mQuestion"
    app:layout_constraintVertical_bias="0.69" />
   </androidx.constraintlayout.widget.ConstraintLayout>

    

【问题讨论】:

    标签: java android android-viewpager2


    【解决方案1】:

    如何确保只有当前页面中的按钮在点击时会改变颜色

    因为 ViewPager2 会在您更改下一页中按钮的颜色时重用布局,所以按钮的颜色是您设置的最后一种颜色。因此,在onBindViewHolder 中,您必须将按钮的颜色更改为默认值:

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position)  {
    
        …
        holder.yes.setBackgroundColor(Color.GREEN);
        holder.yes.setBackgroundColor(Color.LTGRAY);
        
        …
    
    }
    

    如果您只是在点击时更改点击按钮的颜色,您可以使用StateListDrawable 作为背景

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@color/yourPressedColor" />
      <item  android:color="@color/yourNormalColor" />
    </selector>
    

    【讨论】:

    • 如果我在 onBindViewHolder 中设置了默认值,当用户从首页滑动到首页时,它会返回默认值。我希望按钮颜色在单击后保持不变。我怎样才能得到这个?
    • 我尝试在 onBindViewHolder 中设置默认颜色并使用stateRestorationPolicy,但它不起作用。如果转到上一页,颜色仍会更改为默认值。
    【解决方案2】:

    所以我终于找到了答案。其实很容易。就像@mostafa3dmax 说的。我必须在onBindViewHolder 中设置默认颜色。为了使按钮颜色在更改页面后不会重置,我只需要设置

    viewPager2.setOffScreenPageLimit(int value)

    如文档所述:

    在当前页面之外的限制页面内的页面被创建并且 添加到视图层次结构中,即使它们在 屏幕。超出此限制的页面将从视图中删除 层次结构,但 ViewHolders 将像往常一样被回收 回收站视图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多