Reputation: 15
Sorry if this is convoluted...
I'm trying to create an Async Task that updates a value in a recycler view adapter when it's clicked. My problem is I can't get a specific row from the trains LiastArray from the view that's being returned onClick of one of the RecyclerView rows.
public void ArrivalTimeOnClickListener(View view) {
pbArrivalTime = (ProgressBar)view.findViewById(R.id.pbArrivalTime);
tvArrivalTime = (TextView)view.findViewById(R.id.tvArrivalTime);
/**
* GET ADAPTER INDEX HERE
*
* TRIED:
* int trainIndex = rvTrainTimetable.getChildAdapterPosition(view.findViewById(R.id.rlTrainRoot));
*/
new RefreshSingleArrivalTime().execute(view);
}
Essentially, I have a Train class with basic Platform, arrival time, destination etc. fields with getters and setters. I am then setting an adapter with an ArrayList of the Train class, and in ruen assigning the adapter to my RecyclerView:
private void InitializeTrainTimetable() {
trains = new ArrayList<Train>();
trains.add(new Train("Artarmion Platform 3", 7, "On time", "Ahfield", "15:01"));
trains.add(new Train("TEST", 97, "TEST", "TEST", "TEST"));
trainAdapter = new TrainAdapter(this, trains);
rvTrainTimetable = (RecyclerView) findViewById(R.id.rvTrainTimetable);
rvTrainTimetable.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
rvTrainTimetable.setItemAnimator(new DefaultItemAnimator());
rvTrainTimetable.setAdapter(trainAdapter);
}
My TrainAdapter is defined as follows:
public class TrainAdapter extends RecyclerView.Adapter<TrainAdapter.ViewHolder> {
private ArrayList<Train> mTrains;
public TrainAdapter(Context context, ArrayList<Train> trains){
mTrains = trains;
}
/** Inflates xml layout file */
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.train_item, parent, false);
return new ViewHolder(itemView);
}
/** Initialise and assign values for eah row in recycler view */
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Train train = mTrains.get(position);
holder.mArrivalTime.setText(String.format(Constants.REMAINING_MINS, train.getArrivalTime()));
holder.mPlatform.setText(train.getPlatform());
// TOODO: get actual time
holder.mTime.setText("14:14");
holder.mStatus.setText(train.getStatus());
holder.mDestinationTime.setText(train.getDestinationTime());
holder.mDestination.setText(train.getDestination());
}
/** Returns number of items in list */
@Override
public int getItemCount() {
return mTrains.size();
}
/** Initialises xml elements */
class ViewHolder extends RecyclerView.ViewHolder {
public TextView mArrivalTime;
public TextView mPlatform;
public TextView mTime;
public TextView mStatus;
public TextView mDestinationTime;
public TextView mDestination;
/** Initialises xml elements */
public ViewHolder(View itemView) {
super(itemView);
mArrivalTime = (TextView) itemView.findViewById(R.id.tvArrivalTime);
mPlatform = (TextView) itemView.findViewById(R.id.tvPlatform);
mTime = (TextView) itemView.findViewById(R.id.tvTime);
mStatus = (TextView) itemView.findViewById(R.id.tvStatus);
mDestinationTime = (TextView) itemView.findViewById(R.id.tvDestinationTime);
mDestination = (TextView) itemView.findViewById(R.id.tvDestination);
}
}
}
My Train Item layout is defined inside a Relative Layout with 3 LinearLayouts:
<RelativeLayout
android:id="@+id/rlTrainRoot"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/llArrivalTime"
android:layout_width="60dp"
android:layout_height="60dp"
android:orientation="vertical"
android:layout_marginBottom="8dp"
android:layout_marginRight="15dp"
android:layout_marginEnd="15dp"
android:background="@color/ArrivalTimeGreen"
android:onClick="ArrivalTimeOnClickListener">
Upvotes: 1
Views: 2829
Reputation: 1963
You can create custom interface for click handling.
Look my example
public interface RecyclerViewClickListener{
void onItemClick(View view, int position);
}
public class TrainAdapter extends RecyclerView.Adapter<TrainAdapter.ViewHolder> {
private ArrayList<Train> mTrains;
private RecyclerViewClickListener mListener;
public TrainAdapter(Context context, ArrayList<Train> trains, RecyclerViewClickListener listener){
mTrains = trains;
mListener = listener;
}
....
public ViewHolder(final View itemView) {
super(itemView);
mArrivalTime = (TextView) itemView.findViewById(R.id.tvArrivalTime);
mPlatform = (TextView) itemView.findViewById(R.id.tvPlatform);
mTime = (TextView) itemView.findViewById(R.id.tvTime);
mStatus = (TextView) itemView.findViewById(R.id.tvStatus);
mDestinationTime = (TextView) itemView.findViewById(R.id.tvDestinationTime);
mDestination = (TextView) itemView.findViewById(R.id.tvDestination);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onItemClick(itemView, getAdapterPosition());
}
});
.....
in class:
trains.add(new Train("Artarmion Platform 3", 7, "On time", "Ahfield", "15:01"));
trains.add(new Train("TEST", 97, "TEST", "TEST", "TEST"));
trainAdapter = new TrainAdapter(this, trains, new RecyclerViewClickListener(){
@Overide
void onItemClick(View view, int position){
ArrivalTimeOnClickListener(view,position);
}
});
Upvotes: 1
Reputation: 341
You can tag
your view with its position
:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
...
holder.someClickableElement.setTag(position);
...
}
Then in ArrivalTimeOnClickListener
:
public void ArrivalTimeOnClickListener(View view) {
int position = (int) view.getTag();
adapter.mTrains.get(position); // make mTrains public first, or provide getter
...
}
Upvotes: 2