I am making a chat application . App is crashing when i upload an image to Firebase , after selecting image from gallery and start scrolling immediately crash the app, i am using FirebaseRecyclerAdapter .
Error getting package info: com.videocall.newhost
2022-11-16 11:59:23.173 23361-23361 AndroidRuntime pid-23361 E FATAL EXCEPTION: main
Process: com.videocall.newhost, PID: 23361
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionMessageView{c4fbbee position=4 id=-1, oldPos=-1, pLpos:-1 no parent} androidx.recyclerview.widget.RecyclerView{60b9448 VFED..... ........ 0,112-1080,1686 #7f0a01c3 app:id/recyMessage}, adapter:com.videocall.newhost.Adapter.AdapterMessages#9239bff, layout:com.videocall.newhost.Helper.WraperLinearLayout#e8d0fe7, context:com.videocall.newhost.Activity.MessageActivity#8e8b3d4
at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:6544)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6727)
at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288)
at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345)
at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361)
at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368)
at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:233)
at android.os.Looper.loop(Looper.java:344)
at android.app.ActivityThread.main(ActivityThread.java:8212)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)
FirebaseRecyclerAdapter
public class AdapterMessages extends FirebaseRecyclerAdapter<PojoMessages, AdapterMessages.MessageView> {
public AdapterMessages(#NonNull FirebaseRecyclerOptions<PojoMessages> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull MessageView viewHolder, int position, #NonNull PojoMessages pojoMessages) {
if (pojoMessages.isSender()) {
viewHolder.layReciver.setVisibility(View.GONE);
viewHolder.laySender.setVisibility(View.VISIBLE);
switch (pojoMessages.getType()) {
case "text": {
viewHolder.laySText.setVisibility(View.VISIBLE);
viewHolder.laySImage.setVisibility(View.GONE);
viewHolder.laySVoice.setVisibility(View.GONE);
viewHolder.txtSMessage.setText(pojoMessages.getMessage());
break;
}
case "image": {
viewHolder.laySText.setVisibility(View.GONE);
viewHolder.laySImage.setVisibility(View.VISIBLE);
viewHolder.laySVoice.setVisibility(View.GONE);
Picasso.get().load(pojoMessages.getUrl()).into(viewHolder.imgSData);
break;
}
case "voice": {
viewHolder.laySText.setVisibility(View.GONE);
viewHolder.laySImage.setVisibility(View.GONE);
viewHolder.laySVoice.setVisibility(View.VISIBLE);
break;
}
}
} else {
viewHolder.layReciver.setVisibility(View.VISIBLE);
viewHolder.laySender.setVisibility(View.GONE);
switch (pojoMessages.getType()) {
case "text": {
viewHolder.layRText.setVisibility(View.VISIBLE);
viewHolder.layRImage.setVisibility(View.GONE);
viewHolder.layRVoice.setVisibility(View.GONE);
viewHolder.txtRMessage.setText(pojoMessages.getMessage());
break;
}
case "image": {
viewHolder.layRText.setVisibility(View.GONE);
viewHolder.layRImage.setVisibility(View.VISIBLE);
viewHolder.layRVoice.setVisibility(View.GONE);
Picasso.get().load(pojoMessages.getUrl()).into(viewHolder.imgRData);
break;
}
case "voice": {
viewHolder.layRText.setVisibility(View.GONE);
viewHolder.layRImage.setVisibility(View.GONE);
viewHolder.layRVoice.setVisibility(View.VISIBLE);
// viewHolder.voiceRPlayerView.setAudio("https://www2.cs.uic.edu/~i101/SoundFiles/BabyElephantWalk60.wav");
break;
}
}
}
}
#NonNull
#Override
public MessageView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new MessageView(LayoutInflater.from(parent.getContext()).inflate(R.layout.single_message_view, parent, false));
}
public class MessageView extends RecyclerView.ViewHolder {
CircleImageView imgRProfile;
RelativeLayout layRText, layRImage, layRVoice, laySText, laySImage, laySVoice, laySender, layReciver;
TextView txtRMessage, txtSMessage;
ImageView imgRData, imgSData;
public MessageView(#NonNull View itemView) {
super(itemView);
layReciver = itemView.findViewById(R.id.layReciver);
laySender = itemView.findViewById(R.id.laySender);
imgRProfile = itemView.findViewById(R.id.imgRProfile);
layRText = itemView.findViewById(R.id.layRText);
layRVoice = itemView.findViewById(R.id.layRVoice);
layRImage = itemView.findViewById(R.id.layRImage);
txtRMessage = itemView.findViewById(R.id.txtRMessage);
imgRData = itemView.findViewById(R.id.imgRData);
laySText = itemView.findViewById(R.id.laySText);
laySVoice = itemView.findViewById(R.id.laySVoice);
laySImage = itemView.findViewById(R.id.laySImage);
txtSMessage = itemView.findViewById(R.id.txtSMessage);
imgSData = itemView.findViewById(R.id.imgSData);
}
}
}
This adapter is used to populate the chat
I have tried all available solution like extending LayoutManager
public class WraperLinearLayout extends LinearLayoutManager {
public WraperLinearLayout(Context context) {
super(context);
}
public WraperLinearLayout(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public WraperLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
} catch (Exception e) {
Log.d("onLayoutChildren", "onLayoutChildren: "+e.getMessage());
}
}
#Override
public boolean supportsPredictiveItemAnimations() {
return false;
}
}
This is activity where adapter is
public class MessageActivity extends AppCompatActivity {
private static final int SELECT_PICTURE = 2121;
RecyclerView recySuggestion, recyMessage;
AdapterSuggestion adapterSuggestion;
DatabaseReference userDb, myMsgRef, otherMsgRef;
Query query;
AdapterMessages adapterMessages;
EditText edMessage;
ImageView imgSendMsg, imgImageDoc;
WraperLinearLayout layoutManager;
StorageReference imgRef;
ActivityResultLauncher<String> mGetContent = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() {
#Override
public void onActivityResult(Uri result) {
sendImage(result);
}
});
#SuppressLint("ClickableViewAccessibility")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
initialization();
adapterMessages.startListening();
adapterMessages.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = adapterMessages.getItemCount();
int lastVisiblePosition =
layoutManager.findLastCompletelyVisibleItemPosition();
// If the recycler view is initially being loaded or the
// user is at the bottom of the list, scroll to the bottom
// of the list to show the newly added message.
if (lastVisiblePosition == -1 || positionStart >= (friendlyMessageCount - 1)) {
recyMessage.scrollToPosition(positionStart);
}
}
});
onClick();
}
#Override
protected void onResume() {
super.onResume();
}
private void onClick() {
imgSendMsg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendTextMessage(edMessage.getText().toString());
edMessage.setText("");
}
});
imgImageDoc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mGetContent.launch("image/*");
}
});
}
#Override
protected void onStop() {
super.onStop();
adapterMessages.stopListening();
}
private void sendImage(Uri file) {
imgRef.child(file.getLastPathSegment()).putFile(file).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
taskSnapshot.getStorage().getDownloadUrl().addOnCompleteListener(
new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
String fileLink = task.getResult().toString();
//next work with URL
PojoMessages pojoMessages = new PojoMessages();
pojoMessages.setUrl(fileLink);
pojoMessages.setType("image");
pojoMessages.setSender(true);
myMsgRef.push().setValue(pojoMessages);
pojoMessages.setSender(false);
otherMsgRef.push().setValue(pojoMessages);
}
});
}
});
}
private void sendTextMessage(String text) {
PojoMessages pojoMessages = new PojoMessages();
pojoMessages.setMessage(text);
pojoMessages.setType("text");
pojoMessages.setSender(true);
myMsgRef.push().setValue(pojoMessages);
pojoMessages.setSender(false);
otherMsgRef.push().setValue(pojoMessages);
}
private void initialization() {
layoutManager = new WraperLinearLayout(this, LinearLayoutManager.VERTICAL, false);
userDb = FirebaseDatabase.getInstance().getReference().child(USER);
imgRef = FirebaseStorage.getInstance().getReference().child("image/");
myMsgRef = userDb.child("987654321").child(MESSAGE).child("8385958058");
otherMsgRef = userDb.child("8385958058").child(MESSAGE).child("987654321");
query = userDb.child("987654321").child(MESSAGE).child("8385958058");
FirebaseRecyclerOptions<PojoMessages> options = new FirebaseRecyclerOptions.Builder<PojoMessages>()
.setLifecycleOwner(this).setQuery(query, PojoMessages.class).build();
adapterMessages = new AdapterMessages(options);
imgImageDoc = findViewById(R.id.imgImageDoc);
edMessage = findViewById(R.id.edMessage);
imgSendMsg = findViewById(R.id.imgSendMsg);
recySuggestion = findViewById(R.id.recySuggestion);
recyMessage = findViewById(R.id.recyMessage);
recyMessage.setLayoutManager(layoutManager);
recyMessage.setAdapter(adapterMessages);
adapterSuggestion = new AdapterSuggestion();
recySuggestion.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
recySuggestion.setAdapter(adapterSuggestion);
}
}
Related
Hi, I faced an issue here.. I was creating a chatbot in which user can type a text to send it and also can select a text out of the recommended texts
so I created two RecycleViews
My goal is - when the user selects one of the recommended text, then that text should appear in the Chatting RecycleView
here is my main Activity Class
public class Charts extends AppCompatActivity {
private static final String USER_KEY = "user";
private static final String BOT_KEY = "bot";
RecyclerView chart_recycle,auto_texts;
EditText message_text;
ImageView send_btn,mic_button;
ImageView setting_button;
ChartsAdapter chartsAdapter;
RecyclerView.LayoutManager linearLayout;
ArrayList<ChartModeClass> modeClassesArrayList = new ArrayList<>();
AutoAdapter autoAdapter;
RecyclerView.LayoutManager horizontal;
List<Texts> list = new ArrayList();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatting_hole);
message_text = findViewById(R.id.message_text);
send_btn = findViewById(R.id.send_btn);
mic_button = findViewById(R.id.mic_btn);
setting_button = findViewById(R.id.setting_button);
chart_recycle = findViewById(R.id.chart_recycle);
chart_recycle.setHasFixedSize(true);
auto_texts = findViewById(R.id.auto_texts);
auto_texts.setHasFixedSize(true);
linearLayout = new LinearLayoutManager(getApplicationContext(), RecyclerView.VERTICAL, false);
chart_recycle.setLayoutManager(linearLayout);
//Auto text
horizontal = new LinearLayoutManager(getApplicationContext(),RecyclerView.HORIZONTAL, false);
auto_texts.setLayoutManager(horizontal);
chartsAdapter = new ChartsAdapter(modeClassesArrayList, Charts.this);
chart_recycle.setAdapter(chartsAdapter);
//Auto texts
autoAdapter = new AutoAdapter(getApplicationContext(),list);
auto_texts.setAdapter(autoAdapter);
addInputs();
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(Charts.this);
mic_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bottomSheetDialog.setContentView(R.layout.record);
bottomSheetDialog.show();
}
});
message_text.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().length()==0){
mic_button.setVisibility(View.VISIBLE);
send_btn.setVisibility(View.GONE);
}else {
send_btn.setVisibility(View.VISIBLE);
mic_button.setVisibility(View.GONE);
}
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().isEmpty()){
// Toast.makeText(getApplicationContext(),"Enter text",Toast.LENGTH_LONG).show();
mic_button.setVisibility(View.VISIBLE);
send_btn.setVisibility(View.GONE);
}else {
send_btn.setVisibility(View.VISIBLE);
mic_button.setVisibility(View.GONE);
}
}
#Override
public void afterTextChanged(Editable editable) {
if (editable.toString().length()==0){
mic_button.setVisibility(View.VISIBLE);
send_btn.setVisibility(View.GONE);
}
}
});
send_btn.setOnClickListener(view -> {
if (message_text.getText().toString().isEmpty()) {
Toast.makeText(Charts.this, "Please enter text..", Toast.LENGTH_SHORT).show();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
returnResponse(message_text.getText().toString());
}
message_text.setText("");
});
}
#SuppressLint("NotifyDataSetChanged")
private void returnResponse(String message) {
modeClassesArrayList.add(new ChartModeClass(message, USER_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size()-1);
String url = "http://xxxxxxxxxxxxxxxx"+message;
String BASE_URL = "https://xxxxxxxxx";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Call<MessageModeClass> call = retrofitApi.getMessage(url);
call.enqueue(new Callback<MessageModeClass>() {
#Override
public void onResponse(#NonNull Call<MessageModeClass> call, #NonNull Response<MessageModeClass> response) {
if (response.isSuccessful()) {
MessageModeClass messageModeClass = response.body();
if (messageModeClass != null) {
modeClassesArrayList.add(new ChartModeClass(messageModeClass.getCnt(), BOT_KEY));
}
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
} else {
Toast.makeText(Charts.this, "response is null", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(#NonNull Call<MessageModeClass> call, #NonNull Throwable t) {
modeClassesArrayList.add(new ChartModeClass("No response check your network connection!", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}
});
}
#SuppressLint("NotifyDataSetChanged")
#Override
protected void onStart() {
super.onStart();
String lang = getIntent().getExtras().getString("lang");
if (lang.equals("english")){
modeClassesArrayList.add(new ChartModeClass("Hey welcome back am fema bot", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}else if (lang.equals("swahili")){
modeClassesArrayList.add(new ChartModeClass("Habari karibu miminni bot niliyetengenezw", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}else {
modeClassesArrayList.add(new ChartModeClass("Hey welcome back am fema bot", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}
}
private void addInputs() {
Texts text1 = new Texts("gender?");
Texts text2 = new Texts("gender equality");
Texts text3 = new Texts("what is good about females");
Texts text4 = new Texts("un goals");
Texts text5 = new Texts("about men");
list.addAll(Arrays.asList(new Texts[]{text1,text2,text3,text4,text5}));
}
}
here is my Adapter class class codes
public class AutoAdapter extends RecyclerView.Adapter<AutoAdapter.ViewHolderClass> {
Context context;
List<Texts> list;
public AutoAdapter(Context context, List<Texts> list) {
this.context = context;
this.list = list;
}
#NonNull
#Override
public ViewHolderClass onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_list,parent,false);
ViewHolderClass viewHolderClass = new ViewHolderClass(view);
return viewHolderClass;
}
#Override
public void onBindViewHolder(#NonNull ViewHolderClass holder, #SuppressLint("RecyclerView") int position) {
holder.input_text.setText(list.get(position).getText());
holder.input_text.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// my stack
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public class ViewHolderClass extends RecyclerView.ViewHolder {
TextView input_text;
public ViewHolderClass(#NonNull View itemView) {
super(itemView);
input_text = itemView.findViewById(R.id.input_text);
}
}
}
You can add a list of your recommendations in another RecyclerView
Then in the ViewHolder of each item of the RecyclerView add Callback to listen on click events when a user clicks one of the item like the following
public class ViewHolderClass extends RecyclerView.ViewHolder {
private TextView input_text;
private final Callback callback; // custom callback
public ViewHolderClass(#NonNull View itemView, Callback callback) {
super(itemView);
this.callback = callback;
input_text = itemView.findViewById(R.id.input_text);
// now add onClickListener of the itemView to fire custom callback
itemView.setOnClickListener(view -> {
this.callback.onItemClick(getAdapterPosition());
});
}
// this is my custom callback for return click event
public interface Callback {
void onItemClick(int position);
}
}
Now inside your adapter add the callback from viewholder
public class AutoAdapter extends RecyclerView.Adapter<AutoAdapter.ViewHolderClass> {
private Context context;
private List<Texts> list;
private AutoAdapterCallback callback;
public AutoAdapter(Context context, List<Texts> list) {
this.context = context;
this.list = list;
}
public setCallback(AutoAdapterCallback callback) {
this.callback = callback;
}
#NonNull
#Override
public ViewHolderClass onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_list,parent,false);
ViewHolderClass viewHolderClass = new ViewHolderClass(view, new ViewHolderClass.Callback() {
#Override
public void onItemClick(int position) {
// forward callback to adapter callback
if (callback != null) {
// get actual item from its position
final Texts texts = getItemByPosition(position);
// send to adapter callback
callback.onItemClick(texts);
}
});
return viewHolderClass;
}
#Override
public void onBindViewHolder(#NonNull ViewHolderClass holder, #SuppressLint("RecyclerView") int position) {
holder.input_text.setText(list.get(position).getText());
// I haven't used this inteady I added callback on viewholder side
// holder.input_text.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View view) {
// // my stack
// }
// });
}
#Override
public int getItemCount() {
return list.size();
}
// return Texts object by given position
public Texts getItemByPosition(int position) {
return this.list.get(position);
}
// add adapter callback to be called by viewholder
public interface AdapterCallback {
void onItemClick(Texts texts);
}
}
After that, now on your Activity you can easily listen on any item when a user clicks and get its corresponding Texts object from list as following:
//code ...
// here
//Auto texts
autoAdapter = new AutoAdapter(getApplicationContext(),list);
//set callback to listen for click events
autoAdapter.setCallback(new AutoAdapter.AutoAdapterCallback() {
#Override
public void onItemClick(Texts texts) {
// you can get your clicked item here
// now you can put texts object to another RecyclerView :)
}
});
auto_texts.setAdapter(autoAdapter);
//code ...
When I run the app, nothing is visible. Please help me
There seems to be no problem, but I have been wondering about this for a few days.
The debugger shows this warning message:
Android E/RecyclerView: No adapter attached; skipping layout
I don't know what the hell is wrong.
Here is my MainActivity code
private void setUrl(final String dateUrl)
{
myRecyclerView.setAlpha(0.5f);
loadingPanel.setVisibility(View.VISIBLE);
noteTextView.setVisibility(View.GONE);
new Thread(new Runnable() {
#Override
public void run() {
url = "http://data.nba.net/10s/prod/v1/" + dateUrl + "/scoreboard.json";
final RequestQueue requestQueue = Volley.newRequestQueue(NbaApp.getCurrentActivity());
JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET, url,null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
jsonObject = response;
gameCardsCreater = new GameCardsCreater(jsonObject);
if (gameCardsCreater.isGameNight()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
gameCardsCreater.populateCards();
setCardsCreater();
myRecyclerView.setEnabled(true);
myRecyclerView.setVisibility(View.VISIBLE);
loadingPanel.setVisibility(View.GONE);
myRecyclerView.setAlpha(1);
runLayoutAnimation(myRecyclerView);
}
});
} else {
myRecyclerView.setEnabled(false);
myRecyclerView.setVisibility(View.GONE);
noteTextView.setVisibility(View.VISIBLE);
noteTextView.setText(R.string.no_games_tonight);
loadingPanel.setVisibility(View.GONE);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
myRecyclerView.setEnabled(false);
myRecyclerView.setVisibility(View.GONE);
noteTextView.setVisibility(View.VISIBLE);
noteTextView.setText(R.string.error_getting_info);
loadingPanel.setVisibility(View.GONE);
}
});
requestQueue.add(objectRequest);
}
}).start();
}
#SuppressLint("ClickableViewAccessibility")
public void setCardsCreater() {
gameArrayList = new ArrayList<>();
gameArrayList = gameCardsCreater.getGameArrayList();
GameAdapter adapter = new GameAdapter(gameArrayList, new CustomItemClickListener() {
#Override
public void onItemClick(View v, int position) {
if (isNetworkConnected()) {
Intent myIntent = new Intent(MainActivity.this, GameActivity.class);
Bundle extras = new Bundle();
extras.putString("gameDate", gameArrayList.get(position).getGameDate());
extras.putString("gameId", gameArrayList.get(position).getGameId());
extras.putString("homeTeamWins", gameArrayList.get(position).getHomeTeamWins());
extras.putString("awayTeamWins", gameArrayList.get(position).getAwayTeamWins());
extras.putBoolean("isGameActivated", gameArrayList.get(position).isGameActive());
extras.putString("homeTeamName", gameArrayList.get(position).getHomeTeamName());
extras.putString("awayTeamName", gameArrayList.get(position).getAwayTeamName());
extras.putBoolean("isGameOver", gameArrayList.get(position).isGameOver());
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
myIntent.putExtras(extras);
MainActivity.this.startActivity(myIntent);
} else {
Toast.makeText(NbaApp.getCurrentActivity(), "Check your internet connection", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onItemLongClick(View v, int position) {
}
});
myRecyclerView.setHasFixedSize(true);
myRecyclerView.setAdapter(adapter);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
myRecyclerView.setLayoutManager(llm);
}
2.Here is my RecyclerView adapter code, GameAdapter
public class GameAdapter extends RecyclerView.Adapter<GameAdapter.MyViewHolder> {
private final CustomItemClickListener listener;
private ArrayList<Game> gameList;
public GameAdapter(ArrayList<Game> myValues, CustomItemClickListener listener) {
this.gameList = myValues;
this.listener = listener;
}
static class MyViewHolder extends RecyclerView.ViewHolder {
private TextView homeTeamNameTextView;
private TextView awayTeamNameTextView;
private ImageView awayTeamLogoImageView;
private ImageView homeTeamLogoImageView;
private TextView awayTeamScoreTextView;
private TextView homeTeamScoreTextView;
private TextView awayTeamWinsTextView;
private TextView homeTeamWinsTextView;
private TextView nuggetTextView;
private TextView gameTimeTextView;
MyViewHolder(View itemView) {
super(itemView);
awayTeamNameTextView = itemView.findViewById(R.id.awayteamname);
homeTeamNameTextView = itemView.findViewById(R.id.hometeamname);
awayTeamLogoImageView = itemView.findViewById(R.id.awayteamlogo);
homeTeamLogoImageView = itemView.findViewById(R.id.hometeamlogo);
awayTeamScoreTextView = itemView.findViewById(R.id.awayteamscore);
homeTeamScoreTextView = itemView.findViewById(R.id.hometeamscore);
awayTeamWinsTextView = itemView.findViewById(R.id.awayteamwins);
homeTeamWinsTextView = itemView.findViewById(R.id.hometeamwins);
nuggetTextView = itemView.findViewById(R.id.nuggettext);
gameTimeTextView = itemView.findViewById(R.id.gameTime);
}
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View listItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_game, parent, false);
final MyViewHolder myViewHolder = new MyViewHolder(listItem);
listItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(v, myViewHolder.getAdapterPosition());
}
});
return myViewHolder;
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
Game game = gameList.get(position);
holder.homeTeamNameTextView.setText(game.getHomeTeamName());
holder.awayTeamNameTextView.setText(game.getAwayTeamName());
Picasso.get().load(game.getAwayTeamImage()).into(holder.awayTeamLogoImageView);
Picasso.get().load(game.getHomeTeamImage()).into(holder.homeTeamLogoImageView);
holder.awayTeamScoreTextView.setText(game.getAwayTeamScore());
holder.homeTeamScoreTextView.setText(game.getHomeTeamScore());
holder.awayTeamWinsTextView.setText(game.getAwayTeamWins());
holder.homeTeamWinsTextView.setText(game.getHomeTeamWins());
if (game.getNugget().isEmpty())
holder.nuggetTextView.setVisibility(View.GONE);
else
holder.nuggetTextView.setText(game.getNugget());
holder.gameTimeTextView.setText(game.getGameTime());
if (game.isGameActive())
holder.gameTimeTextView.setTextColor(Color.parseColor("#ff0000"));
else
holder.gameTimeTextView.setTextColor(Color.parseColor("#B4B4B4"));
if (!game.getHomeTeamScore().isEmpty() && !game.getAwayTeamScore().isEmpty()) {
if (Integer.parseInt(game.getHomeTeamScore()) > Integer.parseInt(game.getAwayTeamScore())) {
holder.homeTeamScoreTextView.setTextColor(Color.parseColor("#ffffff"));
holder.awayTeamScoreTextView.setTextColor(Color.parseColor("#B4B4B4"));
} else if (Integer.parseInt(game.getHomeTeamScore()) < Integer.parseInt(game.getAwayTeamScore())) {
holder.homeTeamScoreTextView.setTextColor(Color.parseColor("#B4B4B4"));
holder.awayTeamScoreTextView.setTextColor(Color.parseColor("#ffffff"));
} else {
holder.homeTeamScoreTextView.setTextColor(Color.parseColor("#B4B4B4"));
holder.awayTeamScoreTextView.setTextColor(Color.parseColor("#B4B4B4"));
}
}
}
#Override
public int getItemCount() {
return gameList.size();
}
}
Help
the problem is that when running the application nothing appears in my recyclerview, only error android studio : E/RecyclerView: No adapter attached; skipping layout
Salon ListActivity
public class SalonListActivity extends AppCompatActivity implements IOnLoadCountSalon, IBranchLoadListener {
IOnLoadCountSalon iOnLoadCountSalon;
IBranchLoadListener iBranchLoadListener;
AlertDialog dialog;
#BindView(R.id.txt_salon_count)
TextView txt_salon_count;
#BindView(R.id.recycler_salon)
RecyclerView recycler_salon;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_salon_list);
ButterKnife.bind(this);
initView();
init();
loadSalonBaseOnCity(Common.state_name);
}
private void loadSalonBaseOnCity(String name) {
dialog.show();
FirebaseFirestore.getInstance().collection("AllSalon")
.document(name)
.collection("Branch")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful())
{
List<Salon> salons = new ArrayList<>();
iOnLoadCountSalon.onLoadCountSalonSuccess(task.getResult().size());
for(DocumentSnapshot salonSnapShot : task.getResult())
{
Salon salon = salonSnapShot.toObject(Salon.class);
salons.add(salon);
}
iBranchLoadListener.onBranchLoadSuccess(salons);
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
iBranchLoadListener.onBranchLoadFailed(e.getMessage());
}
});
}
private void init() {
dialog = new SpotsDialog.Builder().setContext(this).setCancelable(false).build();
iOnLoadCountSalon=this;
iBranchLoadListener = this;
}
private void initView() {
recycler_salon.setHasFixedSize(true);
recycler_salon.setLayoutManager(new GridLayoutManager(this,2));
recycler_salon.addItemDecoration(new SpacesItemDecoration(8));
}
#Override
public void onLoadCountSalonSuccess(int count) {
txt_salon_count.setText(new StringBuilder("Cantidad Salones (").append(count).append(")"));
}
#Override
public void onBranchLoadSuccess(List<Salon> salonList) {
MySalonAdapter salonAdapter = new MySalonAdapter(this,salonList);
recycler_salon.setAdapter(salonAdapter);
dialog.dismiss();
}
#Override
public void onBranchLoadFailed(String message) {
Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
dialog.dismiss();
}}`
Salon Adapter
public class MySalonAdapter extends RecyclerView.Adapter<MySalonAdapter.MyViewHolder> {
Context context;
List<Salon> salonList;
List<CardView> cardViewList;
LocalBroadcastManager localBroadcastManager;
public MySalonAdapter(Context context, List<Salon> salonList) {
this.context = context;
this.salonList = salonList;
cardViewList = new ArrayList<>();
localBroadcastManager = LocalBroadcastManager.getInstance(context);
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(context).inflate(R.layout.layout_salon, viewGroup, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder myViewHolder, int i) {
myViewHolder.txt_salon_name.setText(salonList.get(i).getName());
myViewHolder.txt_salon_address.setText(salonList.get(i).getAddress());
if (!cardViewList.contains(myViewHolder.card_salon))
cardViewList.add(myViewHolder.card_salon);
myViewHolder.setiRecyckerItemSelectedListener(new IRecyclerItemSelectedListener() {
#Override
public void onItemSelected(View view, int position) {
}
});
}
#Override
public int getItemCount() {
return salonList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
IRecyclerItemSelectedListener iRecyckerItemSelectedListener;
TextView txt_salon_name, txt_salon_address;
CardView card_salon;
public void setiRecyckerItemSelectedListener(IRecyclerItemSelectedListener iRecyckerItemSelectedListener) {
this.iRecyckerItemSelectedListener = iRecyckerItemSelectedListener;
}
public MyViewHolder(#NonNull View itemView) {
super(itemView);
card_salon = (CardView) itemView.findViewById(R.id.card_salon);
txt_salon_name = (TextView) itemView.findViewById(R.id.txt_salon_name);
txt_salon_address = (TextView) itemView.findViewById(R.id.txt_salon_address);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
iRecyckerItemSelectedListener.onItemSelected(v, getAdapterPosition());
}
}
}
Sorry for my English I hope you can help me, I will be very grateful
The message is saying that the adapter is not attached at the time the layout is rendered. Which is true because you've attached it within a callback method
Instead, you can attach it immediately if you create a field of loaded salons and the adapter
IBranchLoadListener iBranchLoadListener;
List<Salon> mSalons = new ArrayList<>();
RecyclerView.Adapter<MySalonAdapter.MyViewHolder> mAdapter;
Use that list in the callback rather than make a new list
if(task.isSuccessful())
{
mSalons.clear();
List<DocumentSnapshot> result = task.getResult();
iOnLoadCountSalon.onLoadCountSalonSuccess(result.size());
for(DocumentSnapshot salonSnapShot : result)
{
Salon salon = salonSnapShot.toObject(Salon.class);
mSalons.add(salon);
}
iBranchLoadListener.onBranchLoadSuccess(mSalons);
}
And then initialize and attach your adapter immediately within the onCreate or init methods rather than wait for the callback
Within onBranchLoadSuccess you should notify the adapter that it needs updated
I am working on RecyclerView and try to using on click listener for each item of recyclcerview using Interface
Here is my Activity class:
public class LegacyHomeActivity extends ActivityBaseDrawer {
private List<LegacyVideo> legacyVideoList = null;
private List<Video> videoList = new ArrayList<>();
private RecyclerView mRecyclerView;
private LegacyModeHomeAdapter adapter;
#Override
public void onNetworkStateChanged(boolean connected) {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
isLegacyMode = true;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_legacy_home);
if (getSupportActionBar() != null) {
setTitle(getString(R.string.footy_legacy_home));
}
ImageView legacy_live_score_imageView = (ImageView) findViewById(R.id.legacy_live_score_imageView);
legacy_live_score_imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(LegacyHomeActivity.this, LegacyLiveScoreActivity.class));
}
});
ImageView legacy_highlight_imageView = (ImageView) findViewById(R.id.legacy_highlight_imageView);
legacy_highlight_imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(LegacyHomeActivity.this, LegacyHighlightsActivity.class));
}
});
ImageView legacy_news_imageView = (ImageView) findViewById(R.id.legacy_news_imageView);
legacy_news_imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(LegacyHomeActivity.this, LegacyNewsActivity.class));
}
});
mRecyclerView = (RecyclerView) findViewById(R.id.legacy_mood_recyclerview);
final LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
adapter = new LegacyModeHomeAdapter(getApplicationContext(), itemClickListener);
mRecyclerView.setAdapter(adapter);
mRecyclerView.setHasFixedSize(true);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setColorSchemeResources(R.color.ThemeColor,
R.color.ThemeColor, R.color.ThemeColor);
swipeRefreshLayout
.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
getLegacyVideoList();
}
});
circularProgressView = (CircularProgressView) findViewById(R.id.circularProgressView);
showLoadingProgress();
getLegacyVideoList();
}
LegacyVideoClickListener itemClickListener = new LegacyVideoClickListener() {
#Override
public void onItemClickListener(int position) {
Video video = videoList.get(position);
VideoPlayerUtil.initVideoPLayer(video, LegacyHomeActivity.this);
}
};
private void getLegacyVideoList() {
FootyLightAPI api = new FootyLightAPI(getApplicationContext(), mResponseListener);
api.getLegacyHomeVideoList();
}
private final FootyLightAPI.ResponseListener mResponseListener = new FootyLightAPI.ResponseListener() {
#Override
public void getResponse(int apiId, final String response) {
switch (apiId) {
case R.integer.ApiLegacyVideoList:
Log.e("Legacy ............", "Response:................" + response);
try {
final ObjectMapper mapper = new ObjectMapper();
legacyVideoList = mapper.readValue(response, new TypeReference<List<LegacyVideo>>() {
});
if (legacyVideoList != null && legacyVideoList.size() > 0) {
videoList.clear();
for (LegacyVideo video : legacyVideoList) {
Log.e("Legacy video", "" + video.getTitle());
Video videoItem = new Video();
if (video.getItemType().equalsIgnoreCase("video")) {
videoItem.setTitle(video.getTitle());
videoItem.setLink(video.getLink());
videoItem.setThumb(video.getThumb());
videoItem.setContentType(video.getContentType());
videoItem.setContentUrl(video.getContentUrl());
videoItem.setDmcaLabel(video.getDmcaLabel());
videoItem.setDmcaContent(video.getDmcaContent());
videoItem.setDmcaDisclaimer(video.getDmcaDisclaimer());
videoItem.setDisplayType(video.getDisplayType());
videoList.add(videoItem);
}
}
}
Log.e("VideoList", "........." + videoList.size());
runOnUiThread(new Runnable() {
#Override
public void run() {
showVideoAdapter();
hideLoadingProgress();
}
});
} catch (Exception e) {
}
break;
default:
break;
}
}
#Override
public void getError(int apiId, int errorCode) {
}
#Override
public void getResponse(String trackingStr, int apiId, String response) {
}
#Override
public void getError(String trackingStr, int apiId, int errorCode) {
}
};
public void showVideoAdapter() {
if (adapter != null) {
adapter.setVideos(videoList);
}
}
}
And here is my Adapter Class
public class LegacyModeHomeAdapter extends RecyclerView.Adapter<LegacyModeHomeAdapter.ItemViewHolder> {
private List<Video> videoList;
private Context mContext;
private LegacyVideoClickListener onVideosRVItemClickListener;
private LayoutInflater getLayoutInflater() {
return LayoutInflater.from(mContext);
}
public LegacyModeHomeAdapter(Context mContext, LegacyVideoClickListener onVideosRVItemClickListener) {
this.mContext = mContext;
this.onVideosRVItemClickListener = onVideosRVItemClickListener;
}
public void setVideos(List<Video> videosList) {
this.videoList = videosList;
notifyDataSetChanged();
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = getLayoutInflater().inflate(R.layout.layout_legacy_mode_home_video_item, parent, false);
return new ItemViewHolder(view);
}
#Override
public void onBindViewHolder(ItemViewHolder holder, final int position) {
Video video = videoList.get(position);
Picasso.with(mContext).load(video.getThumb()).into(holder.categoryImage);
holder.categoryName.setText(video.getTitle());
holder.title_image_btn.setText(video.getDisplayType());
holder.VideosItemClickListener(position, onVideosRVItemClickListener);
}
#Override
public int getItemCount() {
if (videoList != null) {
return videoList.size();
}
return 0;
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView categoryName;
private ImageView categoryImage;
private Button title_image_btn;
public ItemViewHolder(View itemView) {
super(itemView);
categoryName = (TextView) itemView.findViewById(R.id.categoryName);
categoryImage = (ImageView) itemView.findViewById(R.id.categoryImage);
title_image_btn = (Button) itemView.findViewById(R.id.title_image_btn);
}
public void VideosItemClickListener(final int position, final LegacyVideoClickListener videosRVItemClickListener) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
videosRVItemClickListener.onItemClickListener(position);
}
});
}
}
}
And finally i am using this interface for listener :
public interface LegacyVideoClickListener {
public void onItemClickListener(int position);
}
This procedure working fine all of my other portion of app but not working this case. I don't know where is the problem . Please help me .
You this approach:
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final String element = mDataset[position];
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//your code
}
});
}
Pass onVideosRVItemClickListener in your ItemViewHolder constructor.
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = getLayoutInflater().inflate(R.layout.layout_legacy_mode_home_video_item, parent, false);
return new ItemViewHolder(view, onVideosRVItemClickListener);
}
#Override
public void onBindViewHolder(ItemViewHolder holder, final int position) {
Video video = videoList.get(position);
Picasso.with(mContext).load(video.getThumb()).into(holder.categoryImage);
holder.categoryName.setText(video.getTitle());
holder.title_image_btn.setText(video.getDisplayType());
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView categoryName;
private ImageView categoryImage;
private Button title_image_btn;
public ItemViewHolder(View itemView, final LegacyVideoClickListener videosRVItemClickListener) {
super(itemView);
categoryName = (TextView) itemView.findViewById(R.id.categoryName);
categoryImage = (ImageView) itemView.findViewById(R.id.categoryImage);
title_image_btn = (Button) itemView.findViewById(R.id.title_image_btn);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
videosRVItemClickListener.onItemClickListener(getAdapterPosition());
}
});
}
}
Check this sample
OnCLick can be achived using Custom Interface
interface Listener {
void performOperation(int Position);
}
in Your Adapter
private Listener mListener;
In your Adapter initialize your listner in constructor like this
mListener = (Listener) context;
In your bindViewHolder method
holder.yourView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListener.performOperation(position);
}
});
Now in your Activity implement that interface like this
public class LegacyHomeActivity extends ActivityBaseDrawer implements listner {
#Override
public void performOperation(int Position) {
//Do whatever you want to do with this position
}
}
Your interface adapter class should be like this
public class LegacyModeHomeAdapter extends RecyclerView.Adapter<LegacyModeHomeAdapter.ItemViewHolder> {
private List<Video> videoList;
private Context mContext;
public static LegacyVideoClickListener onVideosRVItemClickListener;
private LayoutInflater getLayoutInflater() {
return LayoutInflater.from(mContext);
}
public LegacyModeHomeAdapter(Context mContext, LegacyVideoClickListener onVideosRVItemClickListener) {
this.mContext = mContext;
this.onVideosRVItemClickListener = onVideosRVItemClickListener;
}
public void setVideos(List<Video> videosList) {
this.videoList = videosList;
notifyDataSetChanged();
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = getLayoutInflater().inflate(R.layout.layout_legacy_mode_home_video_item, parent, false);
return new ItemViewHolder(view);
}
#Override
public void onBindViewHolder(ItemViewHolder holder, final int position) {
Video video = videoList.get(position);
Picasso.with(mContext).load(video.getThumb()).into(holder.categoryImage);
holder.categoryName.setText(video.getTitle());
holder.title_image_btn.setText(video.getDisplayType());
holder.VideosItemClickListener(position, onVideosRVItemClickListener);
}
#Override
public int getItemCount() {
if (videoList != null) {
return videoList.size();
}
return 0;
}
public class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView categoryName;
private ImageView categoryImage;
private Button title_image_btn;
public ItemViewHolder(View itemView) {
super(itemView);
categoryName = (TextView) itemView.findViewById(R.id.categoryName);
categoryImage = (ImageView) itemView.findViewById(R.id.categoryImage);
title_image_btn = (Button) itemView.findViewById(R.id.title_image_btn);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
onVideosRVItemClickListener.onItemClickListener(getPosition(), v);
}
}
public void setOnItemClickListener(LegacyVideoClickListener clickListener) {
LegacyModeHomeAdapter.onVideosRVItemClickListener = clickListener;
}
public interface LegacyVideoClickListener {
public void onItemClickListener(int position, View v);
}
}
And your adapter usage class should be like this
adapter.setOnItemClickListener(new LegacyModeHomeAdapter.LegacyVideoClickListener() {
#Override
public void onItemClick(int position, View v) {
//Your code
}
});
Using this way of interface settings you can achieve the onclick listener function exactly.
Please let me know if you are having trouble still.
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public Button btMyButton;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// your implementation. In order to get position you can use `getAdapterPosition()` method
}
}
#Override
public void onBindViewHolder(RecyclerViewAdapter.ItemViewHolder holder, int position) {
holder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
Try like this
When back to previous activity or I get out the app is closed and show this error:
E/RecyclerView: No adapter attached; skipping layout
Within a asycntask in his method onPostExecute I declare a recycleview and RecyclerView.LayoutManager but no have idea what it's wrong. I need your help to solve this problem. Below is my code:
#Override
public void onPostExecute(List<Modules> result) {
if (pDialog.isShowing()){
RecyclerView.LayoutManager Manager =new LinearLayoutManager(DepartureModule.this);
RecyclerView.Adapter adapter = new ModuleAdapter(result);
RecyclerView RVODetails = (RecyclerView) findViewById(R.id.RVODetails);
RVODetails.setLayoutManager(Manager);
RVODetails.setAdapter(adapter);
pDialog.dismiss();
}
and this is my adapter class:
public class ModuleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ItemClickListener itemClickListener;
public final ImageButton Actions;
public final ImageView Image;
public final TextView ModuleCode;
public final TextView ModuleDescription;
public final TextView ModuleDate;
public String ModuleIds;
public ModuleViewHolder(View itemView) {
super(itemView);
Image = (ImageView)itemView.findViewById(R.id.logo);
Actions = (ImageButton)itemView.findViewById(R.id.Actions);
//TitleModuleCode = (TextView)itemView.findViewById(R.id.TitleModuleCode);
ModuleCode = (TextView)itemView.findViewById(R.id.ModuleCode);
//TitleModuleDescription = (TextView)itemView.findViewById(R.id.TitleModuleDescription);
ModuleDescription = (TextView)itemView.findViewById(R.id.ModuleDescription);
ModuleDate = (TextView)itemView.findViewById(R.id.ModuleDate);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
this.itemClickListener.OnItemClick(view,getLayoutPosition());
// Toast.makeText(view.getContext(), "POS" + getLayoutPosition()
// , Toast.LENGTH_LONG).show();
}
public void setItemClickListener(ItemClickListener ItemClick){
this.itemClickListener = ItemClick;
}
}
public ModuleAdapter(List<Modules> Items){
this.Items = Items;
}
#Override
public int getItemCount() {
return Items.size();
}
#Override
public ModuleViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.layout_cardview,viewGroup,false);
return new ModuleViewHolder(view);
}
#Override
public void onBindViewHolder(final ModuleViewHolder ViewHolder, final int position) {
context = ViewHolder.itemView.getContext();
Typeface typeface = Typeface.createFromAsset(context.getAssets(),
"fonts/CaviarDreams.ttf");
ViewHolder.Image.setImageResource(Items.get(position).getImages());
ViewHolder.Actions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ShowPopupMenu(ViewHolder.Actions,position,ViewHolder);
}
});
ViewHolder.ModuleCode.setText(Items.get(position).getModule());
ViewHolder.ModuleCode.setTypeface(typeface); ViewHolder.ModuleDescription.setText(Items.get(position).getDescription());
ViewHolder.ModuleDescription.setTypeface(typeface);
ViewHolder.ModuleDate.setText(Items.get(position).getDate());
ViewHolder.ModuleDate.setTypeface(typeface);
ViewHolder.ModuleIds = Items.get(position).getModuleIds();
ViewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void OnItemClick(View view, int Pos) {
//Toast.makeText(context, "POSITION :" + Pos, Toast.LENGTH_SHORT).show();
}
});
}
private void ShowPopupMenu (final View view, final int position,final ModuleViewHolder holder){
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.action_modify:
final Connection connectionupdate = new Connection(context,Connection.DATABASE_NAME,null,
Connection.DATABASE_VERSION);
final SQLiteDatabase dbUpdate = connectionupdate.getWritableDatabase();
Typeface typeface = Typeface.createFromAsset(context.getAssets(),"fonts/CaviarDreams.ttf");
AlertDialog.Builder ModifyModule = new AlertDialog.Builder(context);
LayoutInflater modifyinflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
final View viewmodify = modifyinflater.inflate(R.layout.layout_custom_dialog_create_modules,null);
TILM = (TextInputLayout)viewmodify.findViewById(R.id.TILM);
TILM.setTypeface(typeface);
TILD = (TextInputLayout)viewmodify.findViewById(R.id.TILD);
TILD.setTypeface(typeface);
ModuleCodeE = (EditText)viewmodify.findViewById(R.id.ModuleCode);
ModuleCodeE.setTypeface(typeface);
ModuleDescE = (EditText)viewmodify.findViewById(R.id.ModuleDesc);
ModuleDescE.setTypeface(typeface);
ModuleCodeE.setText(Items.get(position).getModule());
ModuleDescE.setText(Items.get(position).getDescription());
final String Id = Items.get(position).getModuleIds();
ModifyModule.setView(viewmodify);
ModifyModule.setIcon(R.drawable.logomini);
ModifyModule.setTitle("Construmuebles FM");
ModifyModule.setMessage(" Modifica los valores en los siguientes campos :");
ModifyModule.setPositiveButton("Actualizar", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialogInterface, int i) {
ContentValues VUpdate = new ContentValues();
VUpdate.put(Database.CamposModuloDetails.KEY_MODULE_CODE,ModuleCodeE.getText().toString()); VUpdate.put(Database.CamposModuloDetails.KEY_MODULE_DESC,ModuleDescE.getText().toString());
long IdUpdate = dbUpdate.update(Database.MODULE_DETAILS_TABLE,VUpdate,Database.CamposModuloDetails
.KEY_MODULE_DETAILS_ID + " = ?",new String []{Id});
new UpdateCardView(context,IdUpdate).execute();
dialogInterface.dismiss();
}
});
ModifyModule.setNegativeButton("Cancelar", new DialogInterface
.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
ModifyModule.show();
return true;
case R.id.action_delete:
new DeleteCardView(context,holder,position).execute();
return true;
}
return false;
}
});
menu.show();
}
class DeleteCardView extends AsyncTask<Void,Void,Long>{
private ProgressDialog pDialog;
ModuleViewHolder holder;
int position;
public DeleteCardView(Context context,ModuleViewHolder holder,int position) {
pDialog = new ProgressDialog(context);
this.holder = holder;
this.position = position;
}
#Override
protected void onPreExecute() {
pDialog.setMessage(" Eliminado registro...");
pDialog.show();
}
#Override
protected Long doInBackground(Void... voids) {
String ModuleIdCardView = holder.ModuleIds;
Connection connection = new Connection(context, Connection.DATABASE_NAME, null,
Connection.DATABASE_VERSION);
long i = connection.DeleteByIdCardView(ModuleIdCardView);
if (i != 0) {
return i;
} else {
return i;
}
}
#Override
protected void onPostExecute(Long Result) {
if (pDialog.isShowing()){
pDialog.dismiss();
Items.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position,Items.size());
if (Items.size()==0){ /**viewPager.setCurrentItem(0);**/ }
}
}
}
}
Rearrange your code as follows
recyclerView = (RecyclerView) findViewById(R.id.RVODetails);
mAdapter = new ModuleAdapter(result);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
}