简体   繁体   English

嗨,我是 android 开发人员中的新手,对 viewpager2 中按钮 onclick 的实现有疑问

[英]Hi, im new in android dev and have questions about implementation of button onclick in viewpager2

In my app, i used viewpager2 where user can swipe and answer questions by clicking button yes/no similar like quizzes.在我的应用程序中,我使用了 viewpager2,用户可以在其中通过单击类似测验的按钮是/否来滑动和回答问题。 I've tried to set the button onclicklistener where the button on the current page should change color (yes=green,no=red) when clicked.我试图设置按钮 onclicklistener,点击时当前页面上的按钮应该改变颜色(是=绿色,否=红色)。 The problem is when i click the button sometimes it will change color and sometimes it's not.问题是当我点击按钮时,有时它会改变颜色,有时不会。 When it's not, buttons in back pages also will be affected even though it's not clicked yet.如果不是,即使尚未单击,后页中的按钮也会受到影响。 How to make sure only the button in current page will change color when clicked?如何确保只有当前页面中的按钮在单击时会改变颜色? Is the implementation of button onclick is wrong in my code or what?按钮 onclick 的实现在我的代码中是错误的还是什么? Ive checked the logcat and there is no error shown.我检查了 logcat,没有显示错误。

Here is my MyViewPagerAdapter.java这是我的 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);


    }


}


   }

  

Here is my item_page.xml which is the layout for this:这是我的 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>

    

How to make sure only the button in current page will change color when clicked如何确保只有当前页面中的按钮在单击时会改变颜色

Because ViewPager2 reuses the layouts when you changed the color of a button in the next page the color of button is the last color that you set.因为当您在下一页中更改按钮的颜色时 ViewPager2 会重用布局,所以按钮的颜色是您设置的最后一种颜色。 So in the onBindViewHolder you must change the button's color to default:因此,在onBindViewHolder中,您必须将按钮的颜色更改为默认颜色:

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

    …
    holder.yes.setBackgroundColor(Color.GREEN);
    holder.yes.setBackgroundColor(Color.LTGRAY);
    
    …

}

If you just what to change clicked button color when it clicked you can use a StateListDrawable as it's background如果您只是在单击时更改单击按钮的颜色,则可以使用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>

So finally I found the answer.所以最后我找到了答案。 It's quite easy actually.其实很容易。 Like @mostafa3dmax said.就像@mostafa3dmax 说的。 I have to set the default color in onBindViewHolder .我必须在onBindViewHolder中设置默认颜色。 For the button color to not reset after changing pages, i just have to set为了在更改页面后不重置按钮颜色,我只需要设置

viewPager2.setOffScreenPageLimit(int value) viewPager2.setOffScreenPageLimit(int 值)

As stated in documentation:如文档中所述:

Pages within limit pages away from the current page are created and added to the view hierarchy, even though they are not visible on the screen.在远离当前页面的 limit 页面内的页面被创建并添加到视图层次结构中,即使它们在屏幕上不可见。 Pages outside this limit will be removed from the view hierarchy, but the ViewHolders will be recycled as usual by RecyclerView.超出此限制的页面将从视图层次结构中删除,但 ViewHolders 将像往常一样被 RecyclerView 回收。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM