适配器
public class MoviesAdapter extends
RecyclerView.Adapter<MoviesAdapter.MoviesViewHolder> {
private static final String baseMovieUrl = "http://image.tmdb.org/t/p/w500";
private ArrayList<Movie> movies;
private Context context;
public MoviesAdapter(ArrayList<Movie> movies, Context context) {
this.movies = movies;
this.context = context;
}
@NonNull
@Override
public MoviesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
return new MoviesViewHolder(layoutInflater.inflate(R.layout.movie_square, parent, false));
}
@Override
public void onBindViewHolder(@NonNull MoviesViewHolder holder, int position) {
holder.setData(position);
}
@Override
public int getItemCount() {
return movies.size();
}
public class MoviesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ConstraintLayout movieConstraint;
private TextView movieName;
private TextView movieRate;
private ImageView moviePoster;
public MoviesViewHolder(View itemView) {
super(itemView);
movieConstraint = itemView.findViewById(R.id.movie_holder_constraints);
movieName = itemView.findViewById(R.id.movie_name_tv);
movieRate = itemView.findViewById(R.id.movie_rating_tv);
moviePoster = itemView.findViewById(R.id.movie_iv);
movieConstraint.setOnClickListener(this);
}
public void setData(int position) {
movieConstraint.setTag(position);
movieName.setText(movies.get(position).getMovieName());
movieRate.setText(movies.get(position).getMovieRating() + "");
if (!Objects.equals(movies.get(position).getMovieUrl(), "") && movies.get(position).getMovieUrl() != null) {
Glide.with(moviePoster).load
(baseMovieUrl + movies.get(position).getMovieUrl())
.into(moviePoster);
} else Log.i("No url!", "No url!");
}
@Override
public void onClick(View view) {
int pos = (int) view.getTag();
view.setEnabled(false);
changeActivity(pos);
view.setEnabled(true); // TODO Find a way to prevent 2 acctivites to open simultaniously
}
private void changeActivity(int pos) {
Movie movie = movies.get(pos);
Intent intent = new Intent(context, MovieInfo.class);
intent.putExtra("movie", movie);
ActivityOptionsCompat options = ActivityOptionsCompat.
makeSceneTransitionAnimation((Activity) context, moviePoster, "profile");
context.startActivity(intent, options.toBundle());
}
}
}
和xml
<?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:id="@+id/movie_holder_constraints"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp">
<android.support.v7.widget.CardView
android:id="@+id/movie_cv"
android:layout_width="185dp"
android:layout_height="250dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:focusable="false"
android:focusableInTouchMode="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.constraint.ConstraintLayout
android:id="@+id/inside_movie_constraints"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:focusableInTouchMode="false"
>
<ImageView
android:id="@+id/movie_iv"
android:layout_width="185dp"
android:layout_height="180dp"
android:scaleType="fitXY"
android:focusable="false"
android:focusableInTouchMode="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/ic_launcher" />
<TextView
android:id="@+id/movie_rating_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:text="9.5"
android:textColor="@color/colorAccent"
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/movie_name_tv"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="@+id/movie_name_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Guardian's Of The Galaxy"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintHorizontal_weight="1"
android:gravity="center"
android:includeFontPadding="false"
app:layout_constraintTop_toBottomOf="@+id/movie_iv" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
单击recyclelerView中的项目时,在单击另一个时间调用该函数后,它将不会打开该活动或调用OnClickListener。 滚动也可以让我点击这些项目。
我听说将foucsable改为false可以解决这个问题,但正如你在xml中看到的那样,它并没有。
编辑适配器: 我将onClick更改为onBindViewHolder,它修复了问题,虽然我觉得这样做不是正确的方法。 你怎么说?
package com.example.galzaid.movies;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.constraint.ConstraintLayout;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import java.util.Objects;
public class MoviesAdapter extends
RecyclerView.Adapter<MoviesAdapter.MoviesViewHolder> implements
View.OnClickListener {
private static final String baseMovieUrl = "http://image.tmdb.org/t/p/w500";
private ArrayList<Movie> movies;
private Context context;
public MoviesAdapter(ArrayList<Movie> movies, Context context) {
this.movies = movies;
this.context = context;
}
@NonNull
@Override
public MoviesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
return new MoviesViewHolder(layoutInflater.inflate(R.layout.movie_square, parent, false));
}
@Override
public void onBindViewHolder(@NonNull MoviesViewHolder holder, int position) {
holder.setData(position);
holder.itemView.setOnClickListener(this);
holder.getAdapterPosition();
}
@Override
public int getItemCount() {
return movies.size();
}
@Override
public void onClick(View view) {
ImageView moviePoster = view.findViewById(R.id.movie_iv);
changeActivity((int) view.getTag(), moviePoster);
}
private void changeActivity(int pos, ImageView moviePoster) {
Movie movie = movies.get(pos);
Intent intent = new Intent(context, MovieInfo.class);
intent.putExtra("movie", movie);
ActivityOptionsCompat options = ActivityOptionsCompat.
makeSceneTransitionAnimation((Activity) context, moviePoster, "profile");
context.startActivity(intent, options.toBundle());
}
public class MoviesViewHolder extends RecyclerView.ViewHolder {
private ConstraintLayout movieConstraint;
private TextView movieName;
private TextView movieRate;
private ImageView moviePoster;
public MoviesViewHolder(View itemView) {
super(itemView);
movieConstraint = itemView.findViewById(R.id.movie_holder_constraints);
movieName = itemView.findViewById(R.id.movie_name_tv);
movieRate = itemView.findViewById(R.id.movie_rating_tv);
moviePoster = itemView.findViewById(R.id.movie_iv);
}
public void setData(int position) {
movieConstraint.setTag(position);
movieName.setText(movies.get(position).getMovieName());
movieRate.setText(movies.get(position).getMovieRating() + "");
if (!Objects.equals(movies.get(position).getMovieUrl(), "") && movies.get(position).getMovieUrl() != null) {
Glide.with(moviePoster).load
(baseMovieUrl + movies.get(position).getMovieUrl())
.into(moviePoster);
} else Log.i("No url!", "No url!");
}
}
}
答案 0 :(得分:0)
在绑定方法中设置OnClickListener,在您的情况下为public void setData(int position)
RecyclerView正如其名称所示,正在重用其创建的视图,因此对于每个项目,您应该从一开始就设置所有信息,包括onClick侦听器
这应该可以解决您的问题,并且您可以使用setTag来区分视图
避免在ViewHolder构造函数中设置onClick侦听器。
答案 1 :(得分:0)
我相信你的问题就在这一行
movieConstraint.setOnClickListener(this);
您不应将其设置为ConstraintLayout
,将上述行更改为此
itemView.setOnClickListener(this);
在onClickListener
构造函数中设置ViewHolder
并没有错。
修改强>
为了获得onClick
中的排名,您可以使用getAdapterPosition()
方法。