I need help with me RecyclerView. I've build a normal RecyclerView like this here https://www.raywenderlich.com/126528/android-recyclerview-tutorial and now I need your help.
I want to mark a line (the marked line should be grey) in my RecylcerView on long touch (press) with a short vibration from the device to show a delete icon in the marked row. When the row is marked I want to show the deleting icon instead of the profile image. With clicking the back button from the device I'll remove this mark. How can I do this? Thanks for your help!
Row after long click (press/hold):
This is my adapter:
package de.schoolapp.schoolapp;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
/**
* Created by Johannes on 20.02.2017.
*/
public class BenutzerlisteAdapter extends RecyclerView.Adapter<BenutzerlisteAdapter.MyBenutzerlisteHolder> {
private List<Benutzerliste> userList;
private final Context customContext;
public class MyBenutzerlisteHolder extends RecyclerView.ViewHolder {
public TextView userRowName, userRowPermission;
public MyBenutzerlisteHolder(View view) {
super(view);
userRowName = (TextView) view.findViewById(R.id.userRowName);
userRowPermission = (TextView) view.findViewById(R.id.userRowPermission);
}
}
public BenutzerlisteAdapter(java.util.List<Benutzerliste> userList, Context customContext) {
this.userList = userList;
this.customContext = customContext;
}
#Override
public MyBenutzerlisteHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.benutzerliste_liste_row, parent, false);
return new MyBenutzerlisteHolder(itemView);
}
#Override
public void onBindViewHolder(MyBenutzerlisteHolder holder, int position) {
final Benutzerliste userFillList = userList.get(position);
holder.userRowName.setText(customContext.getString(R.string.userRowName) + " " + userFillList.getVorname() + " " + userFillList.getName());
holder.userRowPermission.setText(customContext.getString(R.string.userRowPermission) + " " + userFillList.getBerechtigung());
// OnClickListener for holder
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
}
});
}
#Override
public int getItemCount() {
return userList.size();
}
}
Related
I am trying to make an app that takes the number of sets, and number of reps for each set from the user, and adds rows ( for each set) and checkboxes (for each rep)
for the reps: i made a method that takes the number of reps from the SQLite server, and loops through the number of reps to make the checkboxes.
for the sets: i made list adapter to make each row.
how can i make the reps be contained inside the rows? thanks.
recyclerview adaptor:
'''
package com.example.workouttracker;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class WorkoutInterfacesAdapter extends RecyclerView.Adapter<WorkoutInterfacesAdapter.WorkoutInterfaceViewHolder> {
Context mContext;
private ArrayList<WorkoutInterfaceClass> sets;
private LinearLayout linearLayout;
public WorkoutInterfacesAdapter(Context mContext , ArrayList<WorkoutInterfaceClass> sets) {
this.sets = sets;
this.mContext = mContext;
}
#NonNull
#Override
public WorkoutInterfaceViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.workout_interface_item,parent,false);
return new WorkoutInterfacesAdapter.WorkoutInterfaceViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull WorkoutInterfacesAdapter.WorkoutInterfaceViewHolder holder, int position) {
holder.bind(sets.get(position));
//new code:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext,"Set number: " + sets.get(position).numberOfSets + " ,Rep Number: "+sets.get(position).numberOfReps,Toast.LENGTH_LONG).show();
Intent intent = new Intent(mContext,WorkoutInterface.class);
intent.putExtra("workout_sets",sets.get(position).numberOfSets);
intent.putExtra("workout_reps",sets.get(position).numberOfReps);
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return sets.size();
}
static class WorkoutInterfaceViewHolder extends RecyclerView.ViewHolder{
TextView numberOfSets;
int numberOfReps;
CheckBox checkBox;
LinearLayout linearLayout;
public WorkoutInterfaceViewHolder(#NonNull View itemView) {
super(itemView);
numberOfSets =itemView.findViewById(R.id.edit_text_number_of_sets_item);
checkBox=itemView.findViewById(R.id.checkbox_number_of_reps_item);
linearLayout=itemView.findViewById(R.id.ll_checkbox_mother);
}
public void bind(WorkoutInterfaceClass sets) {
//
numberOfSets.setText("Set number:" + sets.numberOfSets); ;
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
numberOfReps=sets.numberOfReps;
for (int i = 1; i <= numberOfReps; i++) {
CheckBox checkBox = new CheckBox(linearLayout.getContext());
checkBox.setId(View.generateViewId());
checkBox.setText("Rep: "+checkBox.getId());
checkBox.setOnClickListener((View.OnClickListener) linearLayout.getContext());
System.out.println("Total Number Of Sets:"+numberOfReps + "And the index is : "+ i );
}
}
}}
'''
Try creating a custom layout that will contain all the necessary views and pass the layout in the onCreateView of you adapter class with a layout inflater.
I have a button inside a fragment that is inside an activity. The fragment contains Edittext for user to enter input then press a button and some action is processed. When I click the button I don't even see Log.v output on my logcat tab. That means android is not detecting the onClickListener event. I wonder if is because that event needs to happen in the activity thread and the fragment works in another thread. If someone could clarify how to get this working?
Activity
public class TracerouteActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_traceroute);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
}
Fragment
package org.pctechtips.netdroid.traceroute;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import static android.content.ContentValues.TAG;
public class TraceRouteFragment extends Fragment {
public static final String tag = "TraceroutePing";
public static final String INTENT_TRACE = "INTENT_TRACE";
private Button buttonLaunch;
private EditText editTextPing;
private ProgressBar progressBarPing;
private ListView listViewTraceroute;
private TraceListAdapter traceListAdapter;
protected ProgressDialog scanProgressDialog;
private TracerouteWithPing tracerouteWithPing;
private final int maxTtl = 40;
private List<TracerouteContainer> traces;
/**
* onCreate, init main components from view
*/
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.traceroute, container, false);
this.tracerouteWithPing = new TracerouteWithPing(this);
this.traces = new ArrayList<TracerouteContainer>();
this.buttonLaunch = (Button) view.findViewById(R.id.buttonLaunch);
this.editTextPing = (EditText) view.findViewById(R.id.editTextPing);
this.listViewTraceroute = (ListView) view.findViewById(R.id.listViewTraceroute);
this.progressBarPing = (ProgressBar) view.findViewById(R.id.progressBarPing);
traceListAdapter = new TraceListAdapter(getContext());
listViewTraceroute.setAdapter(traceListAdapter);
buttonLaunch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (editTextPing.getText().length() == 0) {
Toast.makeText(getContext(), getString(R.string.no_text_trace), Toast.LENGTH_SHORT).show();
} else {
traces.clear();
traceListAdapter.notifyDataSetChanged();
startProgressBar();
hideSoftwareKeyboard(editTextPing);
tracerouteWithPing.executeTraceroute(editTextPing.getText().toString(), maxTtl);
}
Log.v(tag, "traceroute to " + editTextPing.getText().toString());
}
});
return view;
}
/**
* initView, init the main view components (action, adapter...)
*/
private void initView() {
}
/**
* Allows to refresh the listview of traces
*/
/*public void refreshList(TracerouteContainer trace) {
final TracerouteContainer fTrace = trace;
runOnUiThread(new Runnable() {
#Override
public void run() {
traces.add(fTrace);
traceListAdapter.notifyDataSetChanged();
}
});
}*/
/**
* The adapter of the listview (build the views)
*/
public class TraceListAdapter extends BaseAdapter {
private Context context;
public TraceListAdapter(Context c) {
context = c;
}
public int getCount() {
return traces.size();
}
public TracerouteContainer getItem(int position) {
return traces.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
// first init
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.item_list_trace, null);
TextView textViewNumber = (TextView) convertView.findViewById(R.id.textViewNumber);
TextView textViewIp = (TextView) convertView.findViewById(R.id.textViewIp);
TextView textViewTime = (TextView) convertView.findViewById(R.id.textViewTime);
ImageView imageViewStatusPing = (ImageView) convertView.findViewById(R.id.imageViewStatusPing);
// Set up the ViewHolder.
holder = new ViewHolder();
holder.textViewNumber = textViewNumber;
holder.textViewIp = textViewIp;
holder.textViewTime = textViewTime;
holder.imageViewStatusPing = imageViewStatusPing;
// Store the holder with the view.
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
TracerouteContainer currentTrace = getItem(position);
if (position % 2 == 1) {
convertView.setBackgroundResource(R.drawable.table_odd_lines);
} else {
convertView.setBackgroundResource(R.drawable.table_pair_lines);
}
if (currentTrace.isSuccessful()) {
holder.imageViewStatusPing.setImageResource(R.drawable.ic_check_green_24dp);
} else {
holder.imageViewStatusPing.setImageResource(R.drawable.ic_close_red_24dp);
}
holder.textViewNumber.setText(position + "");
holder.textViewIp.setText(currentTrace.getHostname() + " (" + currentTrace.getIp() + ")");
holder.textViewTime.setText(currentTrace.getMs() + "ms");
return convertView;
}
// ViewHolder pattern
class ViewHolder {
TextView textViewNumber;
TextView textViewIp;
TextView textViewTime;
ImageView imageViewStatusPing;
}
}
/**
* Hides the keyboard
*
* #param currentEditText The current selected edittext
*/
public void hideSoftwareKeyboard(EditText currentEditText) {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isActive()) {
imm.hideSoftInputFromWindow(currentEditText.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
public void startProgressBar() {
progressBarPing.setVisibility(View.VISIBLE);
getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
scanProgressDialog = new ProgressDialog(getContext(), R.style.NewDialog);
scanProgressDialog.setCancelable(false);
scanProgressDialog.getWindow().setGravity(Gravity.CENTER);
scanProgressDialog.setTitle("Tracing.... Please wait");
scanProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
scanProgressDialog.show();
}
public void stopProgressBar() {
// progressBarPing.setVisibility(View.GONE);
// getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
scanProgressDialog.dismiss();
}
#Override
public void onPause() {
super.onPause();
}
}
In your buttonLaunch.setOnClickListener() method parameter, you have used ' new View.onClickListener(){}', you have to change this to 'new OnClickListener(){}', everything else inside it will be same.
Check out this post for more:
Android Fragment onClick button Method
It should work. Check your adapter to be sure it works fine. Also it best you show us your logs.
try using
buttonLunch = (ImageButton) getActivity().findViewById(R.id.buttonLaunch);
Please am having issue with this null error message java.lang.NullPointerException (no error message). I really need assistance on how and where to add the appropriate code so that the application would not crash. Here is the JAVA file that i am having issues with. I am trying to create a recycler view and jpg images from my drawable folder
HorizontalListAdapter.java
import android.app.Activity;
import android.graphics.Picture;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class HorizontalListAdapter extends RecyclerView.Adapter<HorizontalListAdapter.ViewHolder>
{
private Activity activity;
int[] images= {R.drawable.vb1,R.drawable.pota,R.drawable.vb1,
R.drawable.pota,R.drawable.vb1,R.drawable.download1,R.drawable.pota};
String[] food_items={"prawan","awadhi_lucknow_biryani","eggwraps","chips","mayonnaise","companin","mixvegwrap"};
public HorizontalListAdapter(Activity activity)
{
this.activity = activity;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
LayoutInflater inflater = activity.getLayoutInflater();
View view = inflater.inflate(R.layout.item_horizontal_list, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(HorizontalListAdapter.ViewHolder viewHolder, final int position) {
viewHolder.imageView.setImageResource(images[position]);
viewHolder.txtview.setText(food_items[position].toUpperCase());
viewHolder.linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(activity, "Position clicked: " + position, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return images.length;
}
/**
* View holder to display each RecylerView item
*/
protected class ViewHolder extends RecyclerView.ViewHolder {
private LinearLayout linearLayout;
private ImageView imageView;
private TextView txtview;
public ViewHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.imageview);
txtview = (TextView) view.findViewById(R.id.txtview);
linearLayout = (LinearLayout) view.findViewById(R.id.layout);
}
}
}
The second java class VerticalListAdapter.java
import android.app.Activity;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class VerticalListAdapter extends RecyclerView.Adapter<VerticalListAdapter.ViewHolder> {
private Activity activity;
public VerticalListAdapter(Activity activity) {
this.activity = activity;
}
int[] images= {R.drawable.images,R.drawable.images,R.drawable.images,
R.drawable.images,R.drawable.images,R.drawable.images,R.drawable.images};
String[] food_items={"prawan","awadhi_lucknow_biryani","eggwraps","chips","mayonnaise","companin","mixvegwrap"};
String[] cost={"Rs 200","Rs 300","Rs 150","R 320","Rs 450","Rs 120","Rs 380"};
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = activity.getLayoutInflater();
View view = inflater.inflate(R.layout.item_recycler_view, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
// if ((position + 1) % 2 == 0) {
viewHolder.imageView.setImageResource(images[position]);
viewHolder.txtview.setText(food_items[position].toUpperCase());
viewHolder.txtCost.setText("Cost Per Person "+cost[position]);
// } else {
// viewHolder.imageView.setImageResource(R.drawable.awadhi_lucknow_biryani);
//}
viewHolder.container.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(activity, "Position: " + position, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return images.length;
}
/**
* View holder to display each RecylerView item
*/
protected class ViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView;
private TextView txtview;
private TextView txtCost;
private RelativeLayout container;
public ViewHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.image);
txtview = (TextView) view.findViewById(R.id.text);
txtCost= (TextView) view.findViewById(R.id.textView);
container = (RelativeLayout) view.findViewById(R.id.container);
}
}
}
Please i need assistance with this i guess it is the int[]images causing the error i may be wrong please correct me with the right code i would use to replace and make the code work.
changeimageview accessibility form private to any other modifier & try again
So i have an application where i fetched some poll from an sqlite db and used them in listview and now i tried to add a radio button but when i hit a button back that i created it doesn't save the choice i did from the radio button.
i open the app and...
i choose the second thing
but when i go back and in again the first is selected
here is my listAdapter.java
package com.hfad.myapp.adapter;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RadioButton;
import android.widget.TextView;
import com.hfad.myapp.R;
import com.hfad.myapp.model.Cases;
import java.util.List;
public class ListCases extends BaseAdapter {
private Context mContext;
private List<Cases> mCasesList;
public ListCases(Context mContext, List<Cases> mCasesList) {
this.mContext = mContext;
this.mCasesList = mCasesList;
}
int pose = 0;
#Override
public int getCount() {
return mCasesList.size();
}
#Override
public Object getItem(int position) {
return mCasesList.get(position);
}
#Override
public long getItemId(int position) {
return mCasesList.get(position).getID();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = View.inflate(mContext, R.layout.item_listview, null);
TextView tvName = (TextView)v.findViewById(R.id.tv_case_name);
TextView tvSize = (TextView)v.findViewById(R.id.tv_case_size);
TextView tvMsize = (TextView)v.findViewById(R.id.tv_case_msize);
RadioButton radioButton = (RadioButton)v.findViewById(R.id.radioButton);
radioButton.setChecked(position == pose);
radioButton.setTag(position);
radioButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pose = (Integer)view.getTag();
notifyDataSetChanged();
}
});
tvName.setText(mCasesList.get(position).getBrand());
tvSize.setText(mCasesList.get(position).getSize());
tvMsize.setText(mCasesList.get(position).getMsize());
return v;
}
}
i remind you that i did a database connection with an external database
it's really frustrating i couldn't find something similar and i can't solve this please help.
p.s. for any mistakes...i am really new in java and android studio in general.
I have a RecyclerView class (QuestionCardAdapter) that presents all the items of a SpanishQuestionSet as CardViews.
Everything had been working fine (for instance i could make it so when a card was clicked, 'tick' and 'cross' buttons would come up and would remove the card when clicked)
However recently I wanted the clicking of the buttons (vCross or VTick) to modify an array which is a part of the SpanishQuestionSet (i.e. the item in the array would be +1 for wrong and -1 for right so that the descending quicksort i use will cause questions answered incorrectly to be at the top).
However, whenever I say click 4 consecutive cards as wrong, instead of each card's score being increased by 1, the first card of the 4's score is increased by 4. It seems like getAdapterPosition() is delayed. Could it be affected by a time limit variable I added so that the app wouldnt crash if someone double clicked a button before the card remove animation had completed?
Any help would be appreciated and I will present below the adapter and SpanishQuestionSet classes.
The adapter class is most likely the focus.
package com.alexgower.odin_spanishpack;
import android.content.Context;
import android.graphics.Color;
import android.os.SystemClock;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.util.List;
public class QuestionCardAdapter extends RecyclerView.Adapter<QuestionCardAdapter.QuestionCardViewHolder> {
private final Context context;
protected List<QuestionCardInfo> questionCardList;
private long mLastClickTime = 0;
private SpanishQuestionSet questionSet;
private int positionClicked;
private void setPositionClicked(int i){
this.positionClicked =i;
}
private int getPositionClicked(){
return this.positionClicked;
}
public QuestionCardAdapter(Context contextIn, List<QuestionCardInfo> questionCardList, SpanishQuestionSet questionSetIn) {
this.questionCardList = questionCardList;
this.context = contextIn;
this.questionSet = questionSetIn;
}
#Override
public int getItemCount() {
return questionCardList.size();
}
#Override
public void onBindViewHolder(QuestionCardViewHolder questionCardViewHolder, int i) {
QuestionCardInfo ci = questionCardList.get(i);
questionCardViewHolder.vQuestionAnswer.setText(String.valueOf(ci.score) + ci.question);
questionCardViewHolder.answer = ci.answer;
questionCardViewHolder.vTick.setVisibility(View.INVISIBLE);
questionCardViewHolder.vCross.setVisibility(View.INVISIBLE);
questionCardViewHolder.vColorTV.setBackgroundColor(questionSet.getColourForScore(context,ci.score));
}
#Override
public QuestionCardViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.question_card_layout, viewGroup, false);
return new QuestionCardViewHolder(itemView);
}
public class QuestionCardViewHolder extends RecyclerView.ViewHolder {
public View view;
protected TextView vQuestionAnswer;
protected TextView vColorTV;
protected ImageView vTick;
protected ImageView vCross;
protected String answer = "Error";
public QuestionCardViewHolder(View v) {
super(v);
vColorTV = (TextView) v.findViewById(R.id.forNowColourTextView);
vQuestionAnswer = (TextView) v.findViewById(R.id.questionAnswerTextView);
vTick = (ImageView) v.findViewById(R.id.tickImage);
vCross = (ImageView) v.findViewById(R.id.crossImage);
view = v;
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
vQuestionAnswer.setText(answer);
vTick.setVisibility(View.VISIBLE);
vCross.setVisibility(View.VISIBLE);
setPositionClicked(getAdapterPosition());
}
});
view = vTick;
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (SystemClock.elapsedRealtime() - mLastClickTime > 1000) {
questionSet.questionRight(getPositionClicked(),context);
//questionSet.saveScores(context);
Toast.makeText(context, String.valueOf(questionSet.getScore(getPositionClicked())), Toast.LENGTH_LONG).show();
removeAt(getPositionClicked());
mLastClickTime = SystemClock.elapsedRealtime();
}
}
});
view = vCross;
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (SystemClock.elapsedRealtime() - mLastClickTime > 1000) {
questionSet.questionWrong(getPositionClicked(),context);
Toast.makeText(context, String.valueOf(questionSet.getScore(getPositionClicked())), Toast.LENGTH_LONG).show();
removeAt(getPositionClicked());
mLastClickTime = SystemClock.elapsedRealtime();
}
}
});
}
}
public void testContext(int position) {
questionSet.testFile(position, context);
//String name = questionSet.getQuestion(position);
//try {
// context.openFileOutput("a.txt", Context.MODE_PRIVATE);
// Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
//}catch(FileNotFoundException e){
// Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
//}
}
public void removeAt(int position) {
questionCardList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, questionCardList.size());
}
SpanishQuestionSet class
package com.alexgower.odin_spanishpack;
import android.content.Context;
import android.graphics.Color;
import android.os.SystemClock;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.util.List;
public class QuestionCardAdapter extends RecyclerView.Adapter<QuestionCardAdapter.QuestionCardViewHolder> {
private final Context context;
protected List<QuestionCardInfo> questionCardList;
private long mLastClickTime = 0;
private SpanishQuestionSet questionSet;
private int positionClicked;
private void setPositionClicked(int i){
this.positionClicked =i;
}
private int getPositionClicked(){
return this.positionClicked;
}
public QuestionCardAdapter(Context contextIn, List<QuestionCardInfo> questionCardList, SpanishQuestionSet questionSetIn) {
this.questionCardList = questionCardList;
this.context = contextIn;
this.questionSet = questionSetIn;
}
#Override
public int getItemCount() {
return questionCardList.size();
}
#Override
public void onBindViewHolder(QuestionCardViewHolder questionCardViewHolder, int i) {
QuestionCardInfo ci = questionCardList.get(i);
questionCardViewHolder.vQuestionAnswer.setText(String.valueOf(ci.score) + ci.question);
questionCardViewHolder.answer = ci.answer;
questionCardViewHolder.vTick.setVisibility(View.INVISIBLE);
questionCardViewHolder.vCross.setVisibility(View.INVISIBLE);
questionCardViewHolder.vColorTV.setBackgroundColor(questionSet.getColourForScore(context,ci.score));
}
#Override
public QuestionCardViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.question_card_layout, viewGroup, false);
return new QuestionCardViewHolder(itemView);
}
public class QuestionCardViewHolder extends RecyclerView.ViewHolder {
public View view;
protected TextView vQuestionAnswer;
protected TextView vColorTV;
protected ImageView vTick;
protected ImageView vCross;
protected String answer = "Error";
public QuestionCardViewHolder(View v) {
super(v);
vColorTV = (TextView) v.findViewById(R.id.forNowColourTextView);
vQuestionAnswer = (TextView) v.findViewById(R.id.questionAnswerTextView);
vTick = (ImageView) v.findViewById(R.id.tickImage);
vCross = (ImageView) v.findViewById(R.id.crossImage);
view = v;
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
vQuestionAnswer.setText(answer);
vTick.setVisibility(View.VISIBLE);
vCross.setVisibility(View.VISIBLE);
setPositionClicked(getAdapterPosition());
}
});
view = vTick;
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (SystemClock.elapsedRealtime() - mLastClickTime > 1000) {
questionSet.questionRight(getPositionClicked(),context);
//questionSet.saveScores(context);
Toast.makeText(context, String.valueOf(questionSet.getScore(getPositionClicked())), Toast.LENGTH_LONG).show();
removeAt(getPositionClicked());
mLastClickTime = SystemClock.elapsedRealtime();
}
}
});
view = vCross;
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (SystemClock.elapsedRealtime() - mLastClickTime > 1000) {
questionSet.questionWrong(getPositionClicked(),context);
Toast.makeText(context, String.valueOf(questionSet.getScore(getPositionClicked())), Toast.LENGTH_LONG).show();
removeAt(getPositionClicked());
mLastClickTime = SystemClock.elapsedRealtime();
}
}
});
}
}
public void testContext(int position) {
questionSet.testFile(position, context);
//String name = questionSet.getQuestion(position);
//try {
// context.openFileOutput("a.txt", Context.MODE_PRIVATE);
// Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
//}catch(FileNotFoundException e){
// Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
//}
}
public void removeAt(int position) {
questionCardList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, questionCardList.size());
}
}
Turns out it is quite easy. For anyone in the future with a similar problem, note that getAdapterView() simply returns the integer of a views position in the viewholder so when a view is removed, the next view takes its position.
i.e. if you have views 1,2,3,4,5. When you remove 2, 3 becomes 2 and 4 becomes 3 etc. Alternative explanation: whichever is the 5th view on the screen will have position 5, even if 10000 other items before it have been removed (it will not be position 10005).
So it was not a problem with getAdapterPostion(). To fix the problem I used a variable for an itemID for each view in the recyclerview and did not use getAdapterPosition() except for in the removeAt() method.