My RecyclerView have two problems :
The first problem is when i am finished working with its activity and press back button it creates the same activity again but after removing some row (Mostly from the end) ,, I don't know if the problem is it creates the view on multiple phases or what .
The second problem is when i press some button(Like button for example) it recreates the activity with the new result at each time it is pressed .
here is my Adapter
package com.example.agh.grad.Adapters;
import android.Manifest; import android.app.Activity; import
android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.support.v4.app.ActivityCompat; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import com.example.agh.grad.ItemClickListner; import com.example.agh.grad.Models.Services; import com.example.agh.grad.R; import com.example.agh.grad.SearchServices; import com.example.agh.grad.ServiceDetail; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import org.parceler.Parcels; import java.util.ArrayList; import butterknife.BindView; import butterknife.ButterKnife; /** * Created by cz on 17/06/17. */ public class recylerServiceAdapter extends RecyclerView.Adapter<recylerServiceAdapter.ViewHolder> { ArrayList<Services> service; Context context; ItemClickListner clickListner; public recylerServiceAdapter(ArrayList<Services> service, Context context) { this.service = service; this.context = context; } #Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_recyler_services, parent, false); ViewHolder viewHolder = new ViewHolder(v); context= parent.getContext(); return viewHolder; }
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.tvServiceName.setText(service.get(position).getName());
holder.tvServiceDisrption.setText(service.get(position).getServiceShortDesrption());
holder.tvServiceProvider.setText(service.get(position).getServiceProvider());
holder.tvLikeCounter.setText(String.valueOf(service.get(position).getLikes()));
holder.tvDislikeCounter.setText(String.valueOf(service.get(position).getDislikes()));
holder.tvLocationDescrption.setText(service.get(position).getLocationAddress());
holder.tvServiceName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
/* Intent myIntent= new Intent(context,SearchServices.class);
context.startActivity(myIntent);*/
}
});
holder.btnLike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final FirebaseDatabase firedatabase = FirebaseDatabase.getInstance();
DatabaseReference ref = firedatabase.getReference("Services");
DatabaseReference wantedService = ref.child(String.valueOf(service.get(holder.getAdapterPosition()).getName()));
final Long uplikes= service.get(holder.getAdapterPosition()).getLikes()+1;
wantedService.child("likes").setValue(uplikes, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
holder.tvLikeCounter.setText(String.valueOf(uplikes));
}
});
// TODO: 11/10/17 update on the database
//// TODO: 05/12/17 Check state of buttons and act upon it
holder.btnLike.setClickable(false);//// TODO: 05/12/17 set a clicked icon
holder.btnDislike.setClickable(false);
}
});
holder.btnDislike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final FirebaseDatabase firedatabase = FirebaseDatabase.getInstance();
DatabaseReference ref = firedatabase.getReference("Services");
DatabaseReference wantedService = ref.child(String.valueOf(service.get(holder.getAdapterPosition()).getName()));
final Long dislikes= service.get(holder.getAdapterPosition()).getLikes()-1;
wantedService.child("likes").setValue(dislikes, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
holder.tvLikeCounter.setText(String.valueOf(dislikes));
}
});
}
});
holder.btnCall.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + service.get(holder.getAdapterPosition()).getPhoneNumber()));
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
// TODO: Ask for permission
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
context.startActivity(callIntent);
}
});
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent= new Intent(context,ServiceDetail.class);
myIntent.putExtra(SearchServices.PARCELER_TAG, Parcels.wrap(service.get(holder.getAdapterPosition()) ));
context.startActivity(myIntent);
((Activity)context).finish();
}
});
}
#Override
public int getItemCount() {
return service.size();
}
public void setClickListener(ItemClickListner itemClickListener) {
this.clickListner = itemClickListener;
}
public class ViewHolder extends RecyclerView.ViewHolder {
#BindView (R.id.serviceName) TextView tvServiceName;
#BindView (R.id.serviceProvider)TextView tvServiceProvider;
#BindView (R.id.serviceShortDescrption)TextView tvServiceDisrption;
#BindView (R.id.tvLikeCounter)TextView tvLikeCounter;
#BindView (R.id.tvDislikeCounter)TextView tvDislikeCounter ;
#BindView (R.id.locationDescrption)TextView tvLocationDescrption;
#BindView (R.id.btnLike) Button btnLike;
#BindView (R.id.btnDislike) Button btnDislike;
#BindView (R.id.btnCall) Button btnCall;
#BindView (R.id.serviceCard) CardView cardView;
public ViewHolder(View itemView) {
super(itemView);
itemView.setTag(itemView);
ButterKnife.bind(this, itemView);
}
}
}
and here is my activity
public class MainActivity extends AppCompatActivity {
List<String> arrayServices = new ArrayList<>();
RecyclerView recyclerViewServices;
recylerServiceAdapter recylerServiceAdapter;
ArrayList<Services> newServices;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = this.getIntent();
// arrayServices= intent.getStringArrayListExtra("newServices");
// System.out.println(arrayServices.size());
newServices = Parcels.unwrap(intent.getParcelableExtra(SearchServices.PARCELER_TAG)) ;
Log.e( "onCreate: ",newServices.toString() );
recyclerViewServices = (RecyclerView) findViewById(R.id.recylerViewServiceDetail);
recyclerViewServices.setLayoutManager(new LinearLayoutManager(this));
recylerServiceAdapter = new recylerServiceAdapter(newServices, getApplicationContext());
recyclerViewServices.setAdapter(recylerServiceAdapter);
}
}
and my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/lightPrimary"
tools:context="com.example.agh.grad.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recylerViewServiceDetail"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="5dp"
tools:layout_editor_absoluteY="5dp" />
</RelativeLayout>
instead of using this
holder.tvServiceName.setText(service.get(position).getName());
use
holder.tvServiceName.setText(service.get(getAdapterPosition())
.getName());
Instead of using this in onClick
holder.getAdapterPosition()
use
public void onBindViewHolder(final ViewHolder holder,final int position)
position
Changing activity launch mode to android:launchMode="singleTask" solved the problem
Related
When I create a custom card view in recycler view and click the increment button counter work properply. But when I crete another cardview then already created card counter value reset to 0. How to solve this issue?
Here's my Main Activity code
package com.example.muhasbaapp;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import com.example.muhasbaapp.CustomAdapter.ViewHolder.*;
public class MainActivity extends AppCompatActivity {
private static RecyclerView.Adapter mAdapter,countAdapter;
private RecyclerView.LayoutManager layoutManager,layoutManager2;
private static RecyclerView recyclerView,recyclerView2;
private ImageView imageView;
public CustomModel customModel;
public static ArrayList<String> input = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// myOnClickListener = new MyOnClickListener(this);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView2=(RecyclerView)findViewById(R.id.recycler_view2);
recyclerView.setHasFixedSize(true);
recyclerView2.setHasFixedSize(true);
layoutManager2=new LinearLayoutManager(this);
recyclerView2.setLayoutManager(layoutManager2);
recyclerView2.setItemAnimator(new DefaultItemAnimator());
mAdapter= new CustomAdapter(input);
recyclerView2.setAdapter(mAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.more_action_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) { //add action2 kau kat sini
switch (item.getItemId()) {
case R.id.action_item_1:
openCustomDialoge();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void openCustomDialoge() {
final AlertDialog dialogBuilder = new AlertDialog.Builder(this).create();
LayoutInflater inflater = this.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.user_generated_cards, null);
final EditText editText = (EditText) dialogView.findViewById(R.id.edt_comment);
Button button1 = (Button) dialogView.findViewById(R.id.buttonSubmit);
Button button2 = (Button) dialogView.findViewById(R.id.buttonCancel);
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialogBuilder.dismiss();
}
});
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String s=editText.getText().toString();
if (s.isEmpty()){
Toast.makeText(MainActivity.this, "You can't enter empty spaces", Toast.LENGTH_SHORT).show();
}else {
input.add(s);
recyclerView2.setAdapter(mAdapter);
dialogBuilder.dismiss();
}
}
});
dialogBuilder.setView(dialogView);
dialogBuilder.show();
}
}
And Here' my Adaptar Class code
package com.example.muhasbaapp;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
public ArrayList<String> values;
final CustomModel customMdl=new CustomModel();
final MainActivity mainActivity=new MainActivity();
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView tv;
public View layout;
public TextView counter_value;
public ImageView increment,decrement, deleted;
public int counter;
public ViewHolder(View v) {
super(v);
layout = v;
tv = (TextView) v.findViewById(R.id.textViewName);
counter_value=(TextView) v.findViewById(R.id.counter);
increment=(ImageView)v.findViewById(R.id.increment);
decrement=(ImageView)v.findViewById(R.id.decrement);
deleted=(ImageView)v.findViewById(R.id.delbtn);
}
}
public void add(int position, String item) {
values.add(position, item);
notifyItemInserted(position);
}
public void remove(int position) {
values.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, values.size());
}
// Provide a suitable constructor (depends on the kind of dataset)
public CustomAdapter(ArrayList<String> myDataset) {
this.values = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
LayoutInflater inflater = LayoutInflater.from(
parent.getContext());
View v =
inflater.inflate(R.layout.custom_cards_layout, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
final String name = values.get(position);
holder.tv.setText(name);
final int[] counter={0};
holder.deleted.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
remove(position);
}
});
holder.decrement.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (counter[0] == 0) {
Toast.makeText(v.getContext(), "Can't add less than 0", Toast.LENGTH_SHORT).show();
} else {
counter[0] -= 1;
holder.counter_value.setText(String.valueOf(counter[0]));
}
}
});
holder.increment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.decrement.setEnabled(true);
counter[0] += 1;
holder.counter_value.setText(String.valueOf(counter[0]));
}
});
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return values.size();
}
}
If anyone knows this problem please inform me.
Thanks in advance
Well, I'm seeing some bad practices in your code:
Adapters hosted in main activity must be not static, what do you think if try accessing via recyclerView.getAdapter()
Please remove the next one in your adapter
final MainActivity mainActivity = new MainActivity();
So the problem that you are having is inside your click listener.
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String s = editText.getText().toString();
if (s.isEmpty()) {
Toast.makeText(MainActivity.this, "You can't enter empty spaces", Toast.LENGTH_SHORT).show();
} else {
input.add(s); // <-------------- HERE
recyclerView2.setAdapter(mAdapter);
dialogBuilder.dismiss();
}
}
});
You add the new item to the array, however, the adapter never knows that there is a new item has been added.
Access to the instanced adapter which has been attached to RecyclerView in onCreate() step and update their data.
I have buttons within the rows of a recyclerview within a fragment within an activity. When the user clicks one of the buttons, I want to switch to a different activity. How do I establish context for the Intent to switch to the new activity.
OR, should I move the onClickListener back to the fragment or activity (is it incorrect to place onClickListener within the recyclerview adapter code). If so, how do I obtain reference to the button clicked from outside the recyclerview adapter.
Here is the fragment code (CheckInRecentList.java)
package com.example.checkingin;
import android.app.Application;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.google.android.material.snackbar.Snackbar;
import java.util.List;
import static androidx.constraintlayout.widget.Constraints.TAG;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link CheckInRecentList.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link CheckInRecentList#newInstance} factory method to
* create an instance of this fragment.
*/
public class CheckInRecentList extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private RecyclerView recyclerView;
private RecyclerView.Adapter checkInListAdapter;
//private RecyclerView.LayoutManager layoutManager;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private MainViewModel mViewModel;
private CheckInListAdapter mAdapter;
private MainViewModelProviderFactory viewModelFactory;
private TextView checkInLastDateTime;
private TextView checkInTitle;
private TextView checkInDestinationName;
private TextView checkInComments;
private Context context;
private OnFragmentInteractionListener mListener;
public CheckInRecentList() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment CheckInRecentList.
*/
// TODO: Rename and change types and number of parameters
public static CheckInRecentList newInstance(String param1, String param2) {
CheckInRecentList fragment = new CheckInRecentList();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate: On Create");
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
Log.i(TAG, "onCreateView: On Create View");
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_check_in_recent_list, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
Log.i(TAG, "onButtonPressed: ");
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
Log.i(TAG, "onAttach: OnAttach");
viewModelFactory = new MainViewModelProviderFactory(context.getApplicationContext());
mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
Log.i(TAG,"OnAttach completed");
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i(TAG, "onActivityCreated: On Activity Created");
mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
mAdapter = new CheckInListAdapter(R.layout.fragment_check_in_recent_list);
RecyclerView recyclerView = getView().findViewById(R.id.check_in_recent_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(mAdapter);
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
LinearLayoutManager.VERTICAL));
observerSetup();
Log.i(TAG, "onActivityCreated: Observer SetUp");
ItemTouchHelper.SimpleCallback callback = new
ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT) {
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
mAdapter.deleteItem(position);
Snackbar snackbar = Snackbar.make(viewHolder.itemView, "Item " + (direction == ItemTouchHelper.RIGHT ? "deleted" : "archived") + ".", Snackbar.LENGTH_LONG);
snackbar.setAction(android.R.string.cancel, new View.OnClickListener() {
#Override
public void onClick(View view) {
mAdapter.undoDelete();
}
});
snackbar.show();
}
#Override
public void onChildDraw (Canvas c, RecyclerView
recyclerView, RecyclerView.ViewHolder viewHolder,float dX, float dY,
int actionState, boolean isCurrentlyActive){
new RecyclerViewSwipeDecorator.Builder(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
.addSwipeLeftBackgroundColor(ContextCompat.getColor(getContext(), R.color.recycler_view_item_swipe_left_background))
.addSwipeLeftActionIcon(R.drawable.ic_archive_white_24dp)
.addSwipeRightBackgroundColor(ContextCompat.getColor(getContext(), R.color.recycler_view_item_swipe_right_background))
.addSwipeRightActionIcon(R.drawable.ic_delete_white_24dp)
.addSwipeRightLabel(getString(R.string.action_delete))
.setSwipeRightLabelColor(Color.WHITE)
.addSwipeLeftLabel(getString(R.string.action_archive))
.setSwipeLeftLabelColor(Color.WHITE)
.create()
.decorate();
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);
CustomToast newtoast = new CustomToast(getContext(),"you clicked on this" );
newtoast.show();
}
#Override
public void onDetach() {
super.onDetach();
Log.i(TAG, "onDetach: ");
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
private void clearFields() {
checkInLastDateTime.setText("");
checkInDestinationName.setText("");
checkInTitle.setText("");
checkInComments.setText("");
}
private void observerSetup() {
Log.i(TAG, "observerSetup:");
checkInLastDateTime = getView().findViewById(R.id.checkInLastDateTime);
checkInTitle = getView().findViewById(R.id.checkInTitle);
checkInDestinationName = getView().findViewById(R.id.checkInDestinationName);
checkInComments = getView().findViewById(R.id.checkInComments);
if(mViewModel.getAllCheckIn() != null)
mViewModel.getAllCheckIn().observe(getViewLifecycleOwner(), new Observer<List<CheckInTable>>(){
#Override
public void onChanged(#Nullable final List<CheckInTable> allCheckIn) {
mAdapter.setCheckInList(allCheckIn);
}
});
}
}
Here is the recyclerview adapter code
package com.example.checkingin;
import android.app.Activity;
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.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import static androidx.constraintlayout.widget.Constraints.TAG;
public class CheckInListAdapter extends RecyclerView.Adapter<CheckInListAdapter.ViewHolder>{
private int checkInListLayout;
private List<CheckInTable> checkInList;
private CoordinatorLayout coordinatorLayout;
private RecyclerView recyclerView;
private CheckInTable mRecentlyDeletedItem;
private int mCheckInTablePrimaryKey;
private int mRecentlyDeletedItemPosition;
private Context context;
public CheckInListAdapter(int layoutId) {
Log.i(TAG, "CheckInListAdapter: ");
checkInListLayout = layoutId;
}
public void setCheckInList(List<CheckInTable> allCheckIn) {
checkInList = allCheckIn;
Log.i(TAG, "setCheckInList: ");
notifyDataSetChanged();
}
public void deleteItem(int position) {
mRecentlyDeletedItem = checkInList.get(position);
mRecentlyDeletedItemPosition = position;
checkInList.remove(position);
notifyItemRemoved(position);
}
public void undoDelete() {
checkInList.add(mRecentlyDeletedItemPosition,
mRecentlyDeletedItem);
notifyItemInserted(mRecentlyDeletedItemPosition);
}
#Override
public int getItemCount() {
return checkInList == null ? 0 : checkInList.size();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.i(TAG, "onCreateViewHolder: ");
View view = LayoutInflater.from(
parent.getContext()).inflate(R.layout.recycler_view_item, parent, false);
ViewHolder checkInListViewHolder = new ViewHolder(view);
return checkInListViewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int listPosition) {
TextView checkInTablePrimaryKey = holder.checkInTablePrimaryKey;
TextView checkInLastDateTime = holder.checkInLastDateTime;
TextView checkInTitle = holder.checkInTitle;
TextView checkInDestinationName = holder.checkInDestinationName;
TextView checkInComments = holder.checkInComments;
holder.checkInEditButton.setImageResource(R.drawable.ic_menu_edit);
holder.checkInResendButton.setImageResource(R.drawable.ic_menu_share);
Log.i(TAG, "onBindViewHolder: ");
//checkInTablePrimaryKey.setText(checkInList.get(listPosition).getCheckInTablePrimaryKey());
checkInLastDateTime.setText(checkInList.get(listPosition).getCheckInLastDateTime());
checkInTitle.setText(checkInList.get(listPosition).getCheckInTitle());
checkInDestinationName.setText(checkInList.get(listPosition).getCheckInDestinationName());
checkInComments.setText(checkInList.get(listPosition).getCheckInComments());
ImageView checkInEditButton = holder.checkInEditButton;
ImageView checkInResendButton = holder.checkInResendButton;
ImageButton editCheckInButton = checkInEditButton.findViewById(R.id.checkInEditButton);
ImageButton resendCheckInButton = checkInResendButton.findViewById(R.id.checkInResendButton);
editCheckInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//put in edit check in logic
Integer value = (checkInList.get(listPosition).getCheckInTablePrimaryKey());
Intent intent = new Intent(context, CheckInNew.class);
intent.putExtra("checkInTablePrimaryKey",value);
context.startActivity(intent);
//Bundle extras = getIntent().getExtras();
//if (extras != null) {
// String value = extras.getInt("checkInTablePrimaryKey");
//The key argument here must match that used in the other activity
//}
}
});
resendCheckInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//put in resend logic
}
});
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView checkInTablePrimaryKey;
TextView checkInLastDateTime;
TextView checkInTitle;
TextView checkInDestinationName;
TextView checkInComments;
ImageView checkInEditButton;
ImageView checkInResendButton;
ViewHolder(View itemView) {
super(itemView);
Log.i(TAG, "ViewHolder: ");
checkInTablePrimaryKey = itemView.findViewById(R.id.checkInTablePrimaryKey);
checkInLastDateTime = itemView.findViewById(R.id.checkInLastDateTime);
checkInTitle = itemView.findViewById(R.id.checkInTitle);
checkInDestinationName = itemView.findViewById(R.id.checkInDestinationName);
checkInComments = itemView.findViewById(R.id.checkInComments);
checkInEditButton = itemView.findViewById(R.id.checkInEditButton);
checkInResendButton = itemView.findViewById(R.id.checkInResendButton);
}
}
}
Here is the Activity code CheckIn.java
package com.example.checkingin;
import android.net.Uri;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import android.view.View;
import android.view.Menu;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout;
public class CheckIn extends AppCompatActivity implements
CheckInRecentList.OnFragmentInteractionListener,
CheckInApproveRequested.OnFragmentInteractionListener,
CheckInSearch.OnFragmentInteractionListener {
//private AdView mAdView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_check_in);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
//MobileAds.initialize(this, new OnInitializationCompleteListener() {
// #Override
// public void onInitializationComplete(InitializationStatus initializationStatus) {
// }
//});
//mAdView = findViewById(R.id.adView);
//AdRequest adRequest = new AdRequest.Builder().build();
//mAdView.loadAd(adRequest);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerUtil.getDrawer(this,toolbar);
configureTabLayout();
}
private void configureTabLayout() {
TabLayout tabLayout = findViewById(R.id.check_in_main_tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Recent"));
tabLayout.addTab(tabLayout.newTab().setText("Approve Requested"));
tabLayout.addTab(tabLayout.newTab().setText("Search"));
final ViewPager viewPager = findViewById(R.id.check_in_main_pager);
final PagerAdapter adapter = new CheckInMainPagerAdapter
(getSupportFragmentManager(),
tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new
TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new
TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#Override
public void onFragmentInteraction(Uri uri) {
}
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.check_in, menu);
return true;
}
}
In the constructor of CheckInListAdapter pass another argument as context
public CheckInListAdapter(int layoutId, Context context) {
Log.i(TAG, "CheckInListAdapter: ");
checkInListLayout = layoutId;
this.context = context
}
I'm trying to start a new Fragment that shows the details of the item that was clicked on in the RecyclerView. I've tried this in Activities and it worked perfectly but I'm trying to convert it to use on Fragments. Every time I get an 'null object reference'.
Adapter
package com.umbrella.fragmenttest;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class BorrowedAdapter extends RecyclerView.Adapter<BorrowedAdapter.BorrowedViewHolder> {
private Context mCtx;
private List<Borrowed> borrowedList;
public BorrowedAdapter(Context mCtx, List<Borrowed> borrowedList) {
this.mCtx = mCtx;
this.borrowedList = borrowedList;
}
#Override
public BorrowedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mCtx).inflate(R.layout.list_borrowed, parent, false);
return new BorrowedViewHolder(view);
}
#Override
public void onBindViewHolder(BorrowedViewHolder holder, int position) {
Borrowed b = borrowedList.get(position);
holder.textViewOwner.setText(b.getOwner());
holder.textViewDesc.setText(b.getDesc());
holder.textViewAmount.setText(String.valueOf(b.getAmount()));
}
#Override
public int getItemCount() {
return borrowedList.size();
}
class BorrowedViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView textViewOwner, textViewDesc, textViewAmount;
public BorrowedViewHolder(View itemView) {
super(itemView);
textViewOwner = itemView.findViewById(R.id.b_owner);
textViewDesc = itemView.findViewById(R.id.b_description);
textViewAmount = itemView.findViewById(R.id.b_amount);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Borrowed borrowed = borrowedList.get(getAdapterPosition());
AppCompatActivity activity = (AppCompatActivity) view.getContext();
NavController navController = Navigation.findNavController(activity, R.id.hostfrag);
navController.navigate(R.id.action_displayBorrowed2_to_updateBorrowedClass);
}
}
}
Fragment class with the details
package com.umbrella.fragmenttest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class UpdateBorrowedClass extends Fragment {
private EditText editTextOwner, editTextDesc, editTextAmount;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.new_borrowed, container, false);
editTextOwner = view.findViewById(R.id.u_owner);
editTextDesc = view.findViewById(R.id.u_description);
editTextAmount = view.findViewById(R.id.u_amount);
Bundle bundle = getArguments();
final Borrowed borrowed = (Borrowed) bundle.getSerializable("borrowed");
loadBorrowed(borrowed);
view.findViewById(R.id.button_update).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
updateBorrowed(borrowed);
}
});
view.findViewById(R.id.button_delete).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Are you sure?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
deleteBorrowed(borrowed);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
AlertDialog ad = builder.create();
ad.show();
}
});
return view;
}
private void loadBorrowed(Borrowed borrowed) {
editTextOwner.setText(borrowed.getOwner());
editTextDesc.setText(borrowed.getDesc());
editTextAmount.setText(String.valueOf(borrowed.getAmount()));
}
private void updateBorrowed(final Borrowed borrowed) {
final String sOwner = editTextOwner.getText().toString().trim();
final String sDesc = editTextDesc.getText().toString().trim();
final Double dAmount = Double.parseDouble(editTextAmount.getText().toString().trim());
if (sOwner.isEmpty()) {
editTextOwner.setError("Owner required");
editTextOwner.requestFocus();
return;
}
if (sDesc.isEmpty()) {
editTextDesc.setError("Description required");
editTextDesc.requestFocus();
return;
}
if (dAmount.toString().isEmpty()) {
editTextAmount.setError("Amount required");
editTextAmount.requestFocus();
return;
}
class UpdateBorrowed extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
//Creating an item
borrowed.setOwner(sOwner);
borrowed.setDesc(sDesc);
borrowed.setAmount(dAmount);
//Adding to database
DatabaseClient.getInstance(getContext())
.borrowedDao()
.update(borrowed);
return null;
}
//Returns to the {RecyclerViewFragment} because the item is created
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
DisplayBorrowed displayBorrowed = new DisplayBorrowed();
getChildFragmentManager().beginTransaction().replace(R.id.mainer, displayBorrowed).addToBackStack(null).commit();
Toast.makeText(getContext(), "Updated", Toast.LENGTH_LONG).show();
}
}
UpdateBorrowed ut = new UpdateBorrowed();
ut.execute();
}
private void deleteBorrowed(final Borrowed borrowed) {
class DeleteBorrowed extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
DatabaseClient.getInstance(getContext())
.borrowedDao()
.delete(borrowed);
return null;
}
//Returns to the {RecyclerViewFragment} because the item is created
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
DisplayBorrowed displayBorrowed = new DisplayBorrowed();
getChildFragmentManager().beginTransaction().replace(R.id.mainer, displayBorrowed).addToBackStack(null).commit();
Toast.makeText(getContext(), "Deleted", Toast.LENGTH_LONG).show();
}
}
DeleteBorrowed dt = new DeleteBorrowed();
dt.execute();
}
}
Run log
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.umbrella.fragmenttest, PID: 31428
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.Serializable android.os.Bundle.getSerializable(java.lang.String)' on a null object reference
at com.umbrella.fragmenttest.UpdateBorrowedClass.onCreateView(UpdateBorrowedClass.java:31)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2439)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2646)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2416)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2372)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at androidx.fragment.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Application terminated.
Have a look at this link: https://developer.android.com/guide/navigation/navigation-pass-data#bundle
In your onClick()
#Override
public void onClick(View view) {
Borrowed borrowed = borrowedList.get(getAdapterPosition());
AppCompatActivity activity = (AppCompatActivity) view.getContext();
NavController navController = Navigation.findNavController(activity, R.id.hostfrag);
navController.navigate(R.id.action_displayBorrowed2_to_updateBorrowedClass);
}
You should add a bundle with your borrowed object as argument like below:
#Override
public void onClick(View view) {
Borrowed borrowed = borrowedList.get(getAdapterPosition());
Bundle bundle = new Bundle();
bundle.putSerializable("borrowed", borrowed);
AppCompatActivity activity = (AppCompatActivity) view.getContext();
NavController navController = Navigation.findNavController(activity, R.id.hostfrag);
navController.navigate(R.id.action_displayBorrowed2_to_updateBorrowedClass, bundle);
}
How can I show the recycle view data from ListView to next intent activity by id in card view this is my code please check and show the result
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.example.tanuj.recycleview.Product;
import com.example.tanuj.recycleview.R;
import java.util.List;
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
private TextView textViewTitle,textViewShortDesc,textViewRating,textViewPrice;
private Context mCtx;
private List<Product> productList;
public ProductAdapter(Context mCtx, List<Product> productList) {
this.mCtx = mCtx;
this.productList = productList;
}
#Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.product_list, null);
return new ProductViewHolder(view);
}
#Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
Product product = productList.get(position);
Glide.with(mCtx)
.asBitmap()
.load(product.getImage())
.into(holder.imageView);
holder.textViewTitle.setText(product.getTitle());
holder.textViewShortDesc.setText(product.getShortdesc());
holder.textViewRating.setText(String.valueOf(product.getRating()));
holder.textViewPrice.setText(String.valueOf(product.getPrice()));
holder.textViewTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String data = "{}";
Intent intent = new Intent(mCtx,GalleryActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mCtx.startActivity(intent);
}
});
//Set on click on description
holder.textViewShortDesc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mCtx,"You are click On Description : " +textViewShortDesc,Toast.LENGTH_SHORT).show();
}
});
//Set on click on price
holder.textViewPrice.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mCtx,"You are click On Price",Toast.LENGTH_SHORT).show();
}
});
holder.textViewRating.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(mCtx,"You are click on rating",Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return productList.size();
}
class ProductViewHolder extends RecyclerView.ViewHolder {
TextView textViewTitle, textViewShortDesc, textViewRating, textViewPrice;
ImageView imageView;
public ProductViewHolder(View itemView) {
super(itemView);
textViewTitle = itemView.findViewById(R.id.textViewTitle);
textViewShortDesc = itemView.findViewById(R.id.textViewShortDesc);
textViewRating = itemView.findViewById(R.id.textViewRating);
textViewPrice = itemView.findViewById(R.id.textViewPrice);
imageView = itemView.findViewById(R.id.imageView);
}
}
}
Please make your product class(or model class) implements Parcelable. Android Studio will provide you implementation of parcelable.
Now you can send any your product object in intent extras like Example
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
In my chat App FriendsFragment is shwoing blank. If I want to reflect that then, I have run the app, open the Friends tab in my app and after Instant run in Android studio and it will reflect. If it will not, then I have to add Log statement anywhere in my FriendsFragment, and run Instant run with exctly the open tab of friendsfragmet.
Why I'm telling you to add Log statement is necessary because I found this bug that whenever I change something on my Friends Fragment and then run Instant run, then only it will show the Fragment part. And I have to do this every time, otherwise it won't show. Add Log statement and remove second time, or change tag or change message, do something that makes the changes, and must run Instant run (that Yellow symbol like booster).
NOTE: I'm still doing this thing, I observe this problem by myself and I also don't know why I have to change something every time to show this Fragment? I also built the similar fragment in this same app, but for that there is no problem!
FriendFragment
package com.jimmytrivedi.lapitchat;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
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.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import com.squareup.picasso.Picasso;
import de.hdodenhof.circleimageview.CircleImageView;
public class FriendsFragment extends Fragment {
private RecyclerView FriendRecyclerView;
private DatabaseReference databaseReference, UsersDatabaseReference;
private FirebaseAuth mAuth;
private String currentUID;
private View MainView;
public FriendsFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
MainView = inflater.inflate(R.layout.fragment_friend, container, false);
FriendRecyclerView = MainView.findViewById(R.id.FriendRecyclerView);
mAuth = FirebaseAuth.getInstance();
if (mAuth.getCurrentUser() != null) {
currentUID = mAuth.getCurrentUser().getUid();
databaseReference = FirebaseDatabase.getInstance().getReference().child("Friends").child(currentUID);
databaseReference.keepSynced(true);
UsersDatabaseReference = FirebaseDatabase.getInstance().getReference().child("Users");
UsersDatabaseReference.keepSynced(true);
}
FriendRecyclerView.setHasFixedSize(true);
FriendRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
Log.d("wihddiewd", "Is it going?");
return MainView;
}
#Override
public void onStart() {
super.onStart();
Query query = FirebaseDatabase. getInstance()
.getReference()
.child("Friends")
.limitToLast(50);
FirebaseRecyclerOptions<Friends> options = new FirebaseRecyclerOptions.Builder<Friends>()
.setQuery(query, Friends.class)
.build();
final FirebaseRecyclerAdapter<Friends, FriendsViewHolder> FriendsRecyclerViewAdapter = new
FirebaseRecyclerAdapter<Friends, FriendsViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final FriendsViewHolder holder, int position, #NonNull Friends model) {
holder.setDate(model.getDate());
final String listUID = getRef(position).getKey();
UsersDatabaseReference.child(listUID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
final String userName = dataSnapshot.child("Name").getValue().toString();
String thumbImage = dataSnapshot.child("thumbImage").getValue().toString();
String userOnline = dataSnapshot.child("Online").getValue().toString();
holder.setName(userName);
holder.setThumbImage(thumbImage, getContext());
holder.setUserOnline(userOnline);
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CharSequence options[] = new CharSequence[]{"Open profile", "Send message"};
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Select Options");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
Intent intent = new Intent(getContext(), ProfileActivity.class);
intent.putExtra("userID", listUID);
startActivity(intent);
}
if (which == 1) {
Intent intent = new Intent(getContext(), ChatActivity.class);
intent.putExtra("userID", listUID);
intent.putExtra("userName", userName);
startActivity(intent);
}
}
});
builder.show();
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#NonNull
#Override
public FriendsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.users_single_layout, parent, false);
return new FriendsViewHolder(view);
}
};
FriendRecyclerView.setAdapter(FriendsRecyclerViewAdapter);
FriendsRecyclerViewAdapter.startListening();
}
public static class FriendsViewHolder extends RecyclerView.ViewHolder {
View mView;
public FriendsViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setDate(String date) {
TextView userStatusView = mView.findViewById(R.id.userStatus);
userStatusView.setText(date);
}
public void setName(String name) {
TextView userNameView = mView.findViewById(R.id.userName);
userNameView.setText(name);
}
public void setThumbImage(String thumbImage, Context context) {
CircleImageView circleImageView = mView.findViewById(R.id.userImage);
Picasso.get().load(thumbImage).placeholder(R.drawable.defaultimage)
.into(circleImageView);
}
public void setUserOnline(String online) {
ImageView userOnline = mView.findViewById(R.id.online);
if (online.equals("true")) {
userOnline.setVisibility(View.VISIBLE);
} else {
userOnline.setVisibility(View.INVISIBLE);
}
}
}
}
Update
I know this is weird bug. But basically when I open my app and in app firends tab (which is FriendsFragment.java), it is showing blank. So I tried to debug that is there any mistake on my code or not? But I didn't find. But while debugging time, when I go to my firends tab in my mobile app, and put any log statement in Android Studio (because when I add/remove something so Android Studio will understand that some changes made happen, and then I run Instant run(not normal run) then FriendFragment will reflect and it shows the user list.
And I have to do this every time, (means I have to add something/remove something, that consider changes for Android Studio) then only FriendsFragment will show the users list. And even if I not open my Friends tab, but open something else in app and than run (instant run) that is also not work! Only when I just go to friends tab (that time it is showing blank, but that is okay) and run Instant run, then only it will reflect.
fragment_friends.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FriendsFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/FriendRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
users_single_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/userImage"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginBottom="15dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:src="#drawable/defaultimage" />
<TextView
android:id="#+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignTop="#+id/userImage"
android:layout_marginStart="99dp"
android:text="Display Name"
android:textColor="#000000"
android:textSize="18dp" />
<TextView
android:id="#+id/userStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/userName"
android:layout_below="#+id/userName"
android:text="User default Status"
android:textSize="15dp" />
<ImageView
android:id="#+id/online"
android:layout_width="8dp"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/userName"
android:layout_marginLeft="10dp"
android:layout_toEndOf="#+id/userName"
android:visibility="invisible"
android:src="#drawable/online" />
</RelativeLayout>
Another Fragment ChatFragment, which is similar to this and working pretty fine).
ChatFragment.java
package com.jimmytrivedi.lapitchat;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
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 com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import com.squareup.picasso.Picasso;
import de.hdodenhof.circleimageview.CircleImageView;
public class ChatFragment extends Fragment {
private RecyclerView ConversationList;
private DatabaseReference ConversationRef, MessageRef, UserRef;
private FirebaseAuth mAuth;
private String currentUID;
private View MainView;
public ChatFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
MainView = inflater.inflate(R.layout.fragment_chat, container, false);
ConversationList = MainView.findViewById(R.id.ConversationList);
mAuth = FirebaseAuth.getInstance();
currentUID = mAuth.getCurrentUser().getUid();
ConversationRef = FirebaseDatabase.getInstance().getReference().child("Chat").child(currentUID);
ConversationRef.keepSynced(true);
UserRef = FirebaseDatabase.getInstance().getReference().child("Users");
UserRef.keepSynced(true);
MessageRef = FirebaseDatabase.getInstance().getReference().child("Messages").child(currentUID);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
layoutManager.setReverseLayout(true);
layoutManager.setStackFromEnd(true);
ConversationList.setHasFixedSize(true);
ConversationList.setLayoutManager(layoutManager);
return MainView;
}
#Override
public void onStart() {
super.onStart();
Query conversationQuery = ConversationRef.orderByChild("timestamp");
Query query = FirebaseDatabase.getInstance()
.getReference()
.child("Chat")
.limitToLast(50);
FirebaseRecyclerOptions<Conversation> options = new FirebaseRecyclerOptions.Builder<Conversation>()
.setQuery(query, Conversation.class)
.build();
FirebaseRecyclerAdapter<Conversation, ConversationViewHolder> ConversationRecyclerViewAdapter = new
FirebaseRecyclerAdapter<Conversation, ConversationViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final ConversationViewHolder holder, int position, #NonNull final Conversation model) {
final String listUID = getRef(position).getKey();
Query lastMessageQuery = MessageRef.child(listUID).limitToLast(1);
lastMessageQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
String data = dataSnapshot.child("message").getValue().toString();
holder.setMassage(data, model.isSeen());
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
UserRef.child(listUID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
final String userName = dataSnapshot.child("Name").getValue().toString();
String userThumb = dataSnapshot.child("thumbImage").getValue().toString();
if (dataSnapshot.hasChild("Online")) {
String userOnline = dataSnapshot.child("Online").getValue().toString();
holder.setUserOnline(userOnline);
}
holder.setName(userName);
holder.setUserImage(userThumb, getContext());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), ChatActivity.class);
intent.putExtra("userID", listUID);
intent.putExtra("userName", userName);
startActivity(intent);
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#NonNull
#Override
public ConversationViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.users_single_layout, parent, false);
return new ConversationViewHolder(view);
}
};
ConversationList.setAdapter(ConversationRecyclerViewAdapter);
ConversationRecyclerViewAdapter.startListening();
}
public static class ConversationViewHolder extends RecyclerView.ViewHolder {
View mView;
public ConversationViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setMassage(String message, boolean isSeen) {
TextView userStatusView = mView.findViewById(R.id.userStatus);
userStatusView.setText(message);
if (!isSeen) {
userStatusView.setTypeface(userStatusView.getTypeface(), Typeface.BOLD);
} else {
userStatusView.setTypeface(userStatusView.getTypeface(), Typeface.NORMAL);
}
}
public void setUserOnline(String online) {
ImageView userOnlineView = mView.findViewById(R.id.online);
if (online.equals("true")) {
userOnlineView.setVisibility(View.VISIBLE);
} else {
userOnlineView.setVisibility(View.INVISIBLE);
}
}
public void setName(String userName) {
TextView userNameView = mView.findViewById(R.id.userName);
userNameView.setText(userName);
}
public void setUserImage(String userThumb, Context context) {
CircleImageView userImageView = mView.findViewById(R.id.userImage);
Picasso.get().load(userThumb).placeholder(R.drawable.defaultimage).into(userImageView);
}
}
}
Friends.java
package com.jimmytrivedi.lapitchat;
public class Friends {
public String date;
public Friends() {
}
public Friends(String date) {
this.date = date;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
SectionPagerAdapter.java
package com.jimmytrivedi.lapitchat;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
RequestFragment requestFragment = new RequestFragment();
return requestFragment;
case 1:
ChatFragment chatFragment = new ChatFragment();
return chatFragment;
case 2:
FriendsFragment friendFragment = new FriendsFragment();
return friendFragment;
default:
return null;
}
}
#Override
public int getCount() {
return 3;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Requests";
case 1:
return "Chats";
case 2:
return "Friends";
default:
return null;
}
}
}
MainActivity.java
package com.jimmytrivedi.lapitchat;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import com.facebook.login.LoginManager;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ServerValue;
public class MainActivity extends AppCompatActivity {
private FirebaseAuth mAuth;
private FirebaseUser currentUser;
private Toolbar toolbar;
private ViewPager viewPager;
private SectionsPagerAdapter sectionsPagerAdapter;
private TabLayout tabLayout;
private DatabaseReference UserDatabaseReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
currentUser = mAuth.getCurrentUser();
if (currentUser == null) {
sendTostart();
} else {
UserDatabaseReference = FirebaseDatabase.getInstance().getReference().child("Users").child(mAuth.getCurrentUser().getUid());
UserDatabaseReference.child("Online").setValue("true");
}
viewPager = findViewById(R.id.viewPager);
sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(sectionsPagerAdapter);
toolbar = findViewById(R.id.mainToolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Home");
tabLayout = findViewById(R.id.tabLayout);
tabLayout.setupWithViewPager(viewPager);
}
#Override
protected void onPause() {
super.onPause();
if (currentUser != null) {
UserDatabaseReference.child("Online").setValue(ServerValue.TIMESTAMP);
}
}
private void sendTostart() {
startActivity(new Intent(MainActivity.this, StartActivity.class));
finish();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
if (item.getItemId() == R.id.logout) {
FirebaseAuth.getInstance().signOut();
LoginManager.getInstance().logOut();
sendTostart();
}
if (item.getItemId() == R.id.settings) {
startActivity(new Intent(MainActivity.this, SettingsActivity.class));
}
if (item.getItemId() == R.id.allUsers) {
startActivity(new Intent(MainActivity.this, UsersActivity.class));
}
return true;
}
}
Use
`viewPager.setOffscreenPageLimit(3);`
after
viewPager.setAdapter(sectionsPagerAdapter);
inside MainActivity.
Use notifyDataSetChanged() after setting adapter to recyclerview.
FriendRecyclerView.setAdapter(FriendsRecyclerViewAdapter);
FriendsRecyclerViewAdapter.notifyDataSetChanged();