Reload fragment from Adapter class - java

I have BottomNavigationView where i display fragments and i have adapter named FavoriteRecViewAdapter related on FavoritFragment.java, i need to reload FavoritFragment if one of favorites was deleted
I have BottomNavigationView where i display fragments and i have adapter named FavoriteRecViewAdapter related on FavoritFragment.java, i need to reload FavoritFragment if one of favorites was deleted
sorry for spam stackoverflow forced me ;)
FavoritFragment.java :
public class FavoriFragment 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 List<Favorite> favorites;
private RecyclerView favoriteRecView;
private FloatingActionButton fabAddFavorite;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public FavoriFragment() {
// 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 FavoriFragment.
*/
// TODO: Rename and change types and number of parameters
public static FavoriFragment newInstance(String param1, String param2) {
FavoriFragment fragment = new FavoriFragment();
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);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_favori, container, false);
favoriteRecView = (RecyclerView) rootView.findViewById(R.id.favoriteRecView);
fabAddFavorite = rootView.findViewById(R.id.fabAddFavorite);
favorites = new ArrayList<>();
Retrofit retrofit = RetrofitClientInstance.getRetrofitInstance(getContext());
final FavoriteAPI favoriteAPI = retrofit.create(FavoriteAPI.class);
Call<List<Favorite>> call = favoriteAPI.getFavorites();
call.enqueue(new Callback<List<Favorite>>() {
#Override
public void onResponse(Call<List<Favorite>> call, Response<List<Favorite>> response) {
if(response.code() != 200) {
Toast.makeText(getContext(), "Something wrong", Toast.LENGTH_SHORT).show();
} else {
List<Favorite> favoriteList = response.body();
for(Favorite favorite : favoriteList) {
favorites.add(favorite);
}
initData(favorites);
}
}
#Override
public void onFailure(Call<List<Favorite>> call, Throwable t) {
}
});
fabAddFavorite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), AddFavoriActivity.class);
getContext().startActivity(intent);
}
});
return rootView;
}
private void initData(List<Favorite> favorites) {
FavoriteRecViewAdapter favoriteRecViewAdapter = new FavoriteRecViewAdapter(favorites, getContext());
favoriteRecView.setAdapter(favoriteRecViewAdapter);
favoriteRecView.setLayoutManager(new LinearLayoutManager(getContext()));
}
}
FavoriteRecViewAdapter.java :
public class FavoriteRecViewAdapter extends RecyclerView.Adapter<FavoriteRecViewAdapter.viewHolder>{
private List<Favorite> favorites;
private Context mContext;
public FavoriteRecViewAdapter(List<Favorite> favorites, Context mContext) {
this.favorites = favorites;
this.mContext = mContext;
}
public FavoriteRecViewAdapter(List<Favorite> favorites) {
this.favorites = favorites;
}
#NonNull
#Override
public viewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.favorites_list_item, parent, false);
return new viewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull viewHolder holder, int position) {
holder.favoriteLibelle.setText(favorites.get(position).getCarte().getLibelle());
holder.favoriteNumero.setText(String.valueOf(favorites.get(position).getCarte().getNumero()));
holder.favoriteComments.setText(favorites.get(position).getComments());
holder.favoriteDate.setText(favorites.get(position).getDate());
holder.deleteFavoriteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String msg = "are your sure ! you want to delete " +
favorites.get(holder.getAdapterPosition()).getCarte().getLibelle() +
" from favorites";
new MaterialAlertDialogBuilder(mContext)
.setTitle("Delete favorite")
.setMessage(msg)
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setPositiveButton("Yes delete it", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Retrofit retrofit = RetrofitClientInstance.getRetrofitInstance(mContext);
final FavoriteAPI favoriteAPI = retrofit.create(FavoriteAPI.class);
Call<String> call = favoriteAPI.deleteFavorite(
favorites.get(holder.getAdapterPosition()).getId()
);
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.code() == 204) {
showSnackBarSuccess("Favorite was delete successfully");
} else{
showSnackBarError("Some thing wrong please try again !");
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
}
});
}
})
.show();
}
});
}
#Override
public int getItemCount() {
return favorites.size();
}
public class viewHolder extends RecyclerView.ViewHolder{
private TextView favoriteLibelle;
private TextView favoriteNumero;
private TextView favoriteComments;
private TextView favoriteDate;
private Button deleteFavoriteBtn;
public viewHolder(#NonNull View itemView) {
super(itemView);
favoriteLibelle = itemView.findViewById(R.id.favoriteLibelle);
favoriteNumero = itemView.findViewById(R.id.favoriteNumero);
favoriteComments = itemView.findViewById(R.id.favoriteComments);
favoriteDate = itemView.findViewById(R.id.favoriteDate);
deleteFavoriteBtn = itemView.findViewById(R.id.deleteFavoriteBtn);
}
}
private void showSnackBarError(String msg) {
Snackbar.make(((Activity) mContext).findViewById(android.R.id.content), msg, Snackbar.LENGTH_SHORT)
.setTextColor(ContextCompat.getColor(mContext,R.color.white))
.setBackgroundTint(ContextCompat.getColor(mContext,R.color.danger))
.show();
}
private void showSnackBarSuccess(String msg) {
Snackbar.make(((Activity) mContext).findViewById(android.R.id.content), msg, Snackbar.LENGTH_SHORT)
.show();
}
}
Thanks for any help ;)

Related

How can I refresh RecyclerView after adding new data?

How can I refresh the RecyclerView after adding a new item, Note that I'm using a hub connection to send and receive messages from the back-end side, and I'm trying to use notifyItemRangeChanged to refresh the RecyclerView but it does not work,
Here is the adapter class:
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder> {
public static final int MSG_TYPE_LEFT = 0;
public static final int MSG_TYPE_RIGHT = 1;
public static int i = 0;
private Context mContext;
private List<Chat> mChat;
private String imageurl;
public MessageAdapter(Context mContext, List<Chat> mChat, String imageurl) {
this.mContext = mContext;
this.mChat = mChat;
this.imageurl = imageurl;
}
#NonNull
#Override
public MessageAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if(viewType == MSG_TYPE_RIGHT){
View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_right, parent, false);
return new MessageAdapter.ViewHolder(view);
}else{
View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_left, parent, false);
return new MessageAdapter.ViewHolder(view);
}
}
#Override
public void onBindViewHolder(#NonNull MessageAdapter.ViewHolder holder, int position) {
Chat chat = mChat.get(position);
holder.show_message.setText(chat.getMessage());
holder.profile_image.setImageResource(R.mipmap.ic_launcher);
holder.setItem_on_click_listener(new item_on_click_listener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Toast.makeText(mContext, "Clicked", Toast.LENGTH_LONG).show();
}
});
}
#Override
public int getItemCount() {
return mChat.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener{
public TextView show_message;
public ImageView profile_image;
private item_on_click_listener item_on_click_listener;
public ViewHolder(View itemView) {
super(itemView);
show_message = itemView.findViewById(R.id.show_message);
profile_image = itemView.findViewById(R.id.profile_image);
}
public void setItem_on_click_listener(item_on_click_listener item_on_click_listener){
this.item_on_click_listener = item_on_click_listener;
}
#Override
public void onClick(View view) {
item_on_click_listener.onClick(view, getAdapterPosition(), false);
}
#Override
public boolean onLongClick(View view) {
item_on_click_listener.onClick(view, getAdapterPosition(), false);
return true;
}
}
#Override
public int getItemViewType(int position) {
i = position;
if(mChat.get(position).getSender() == "Sender Name"){
return MSG_TYPE_RIGHT;
}
else{
return MSG_TYPE_LEFT;
}
}
#Override
public void onAttachedToRecyclerView(#NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
recyclerView.refreshDrawableState();
}
}
Here is the main-activity class:
public class MainActivity extends AppCompatActivity {
Button sendBtn;
ArrayList<String> messagesList = new ArrayList<>();
HubConnection hubConnection;
EditText edt_text;
TextView txt_received;
MessageAdapter messageAdapter;
List<Chat> mChat;
RecyclerView recyclerView;
public void readMessages(String sender, String receiver, String message){
Chat chat = new Chat(sender, receiver, message);
mChat.add(chat);
messageAdapter = new MessageAdapter(MainActivity.this, mChat, "default");
recyclerView.setAdapter(messageAdapter);
messageAdapter.notifyItemRangeChanged(messageAdapter.getItemCount(), mChat.size());
}
#SuppressLint("WrongThread")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
mChat = new ArrayList<>();
messageAdapter = new MessageAdapter(MainActivity.this, mChat, "default");
recyclerView.setAdapter(messageAdapter);
sendBtn = findViewById(R.id.send_btn);
edt_text = findViewById(R.id.edt_text);
try {
hubConnection = HubConnectionBuilder.create("URL").build();
hubConnection.start();
AtomicReference<String> state = new AtomicReference<>("");
hubConnection.start().subscribe(() -> {
state.set("Connect");
},
error -> {
state.set("error");
});
hubConnection.on("SendMessage", (param1, param2, param3, param4) -> {
readMessages("Sender Name", "Receiver Name", "Message");
}, String.class, String.class, String.class, Integer.class);
}
catch (Exception e){
String exMessage = e.getMessage();
}
sendBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
if(edt_text.getText().toString().length() > 0){
if(hubConnection.getConnectionState() == HubConnectionState.DISCONNECTED){
hubConnection.start();
}
hubConnection.send("Method Name", "param1", "param2", "param3", "param4");
hubConnection.on("ReceiveMessage", (param1, param2, param3 , param4) -> {
readMessages("Sender Name", "Receiver Name", "Message");
}, String.class, String.class, String.class, Integer.class);
}
else{
edt_text.setHint("Can not be empty");
}
}catch (Exception ex){
String message ;
message = ex.getMessage();
}
}
});
}
}
Can anyone help me, please?
notifyItemRangeChanged will work if you add/remove the data in same instance of Adapter or any other notify method for that matter. The problem here is you are creating a new Adapter every time inside your readMessages method.
Create adapter only once and notify it as needed .. Since you already created the messageAdapter inside onCreate you can use the same instance.
public void readMessages(String sender, String receiver, String message){
Chat chat = new Chat(sender, receiver, message);
mChat.add(chat);
messageAdapter.notifyItemRangeChanged(messageAdapter.getItemCount(), mChat.size());
}

notifyDataSetChanged() blanks out recyclerview

I have an issue where notifyDataSetChanged() in a response call will blank out the recyclerview but if the Adapter is initiated manually with a onClick, the recyclerview works. I have tested that the List has the items inside before calling notifyDataSetChanged() so i'm not sure what's wrong here.
[Main Activity] This works but i have to manually click the bnQuery.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiInterface = API_client.getClient().create(APIInterface.class);
etCoin = (EditText) findViewById(R.id.etCoin);
bnQuery = (Button) findViewById(R.id.bnQuery);
rcvMain = findViewById(R.id.rcvMain);
getCoinData("2");
//initRCV_Main();
bnQuery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//getCoinData("2");
initRCV_Main();
}
});
}
private void initRCV_Main() {
rcvMainAdp = new rcvMainAdapter(cList);
rcvMain.setAdapter(rcvMainAdp);
rcvMain.setLayoutManager(new LinearLayoutManager(this));
}
private void getCoinData(String coinLimit){
Call<cInfoPack> call = apiInterface.doGetCoinData(coinLimit);
call.enqueue(new Callback<cInfoPack>() {
#Override
public void onResponse(Call<cInfoPack> call, Response<cInfoPack> response) {
cInfoPack list = response.body();
List<cData> listSorter = new ArrayList<>();
listSorter.addAll(list.getData());
Collections.sort(listSorter, new SortbyVolChg());
cList.clear();
cList = listSorter;
System.out.println("list " + list.getData().get(0).getQuote());
System.out.println("listSorter " + listSorter.get(0).getQuote());
System.out.println("cList " + cList.get(0).getQuote());
//rcvMainAdp.notifyDataSetChanged();
}
#Override
public void onFailure(Call<cInfoPack> call, Throwable t) {
Toast.makeText(MainActivity.this, "onFailure", Toast.LENGTH_SHORT).show();
Log.d("XXXX", t.getLocalizedMessage());
call.cancel();
}
});
}
[Main Activity] If i initiate the recyclerview during onCreate and use the notifyDataSetChanged() during getCoinData, I get a blank recycleview. system.out shows that the lists all contain information in them.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiInterface = API_client.getClient().create(APIInterface.class);
etCoin = (EditText) findViewById(R.id.etCoin);
bnQuery = (Button) findViewById(R.id.bnQuery);
rcvMain = findViewById(R.id.rcvMain);
getCoinData("2");
initRCV_Main();
bnQuery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//getCoinData("2");
//initRCV_Main();
}
});
}
private void initRCV_Main() {
rcvMainAdp = new rcvMainAdapter(cList);
rcvMain.setAdapter(rcvMainAdp);
rcvMain.setLayoutManager(new LinearLayoutManager(this));
}
private void getCoinData(String coinLimit){
Call<cInfoPack> call = apiInterface.doGetCoinData(coinLimit);
call.enqueue(new Callback<cInfoPack>() {
#Override
public void onResponse(Call<cInfoPack> call, Response<cInfoPack> response) {
cInfoPack list = response.body();
List<cData> listSorter = new ArrayList<>();
listSorter.addAll(list.getData());
Collections.sort(listSorter, new SortbyVolChg());
cList.clear();
cList = listSorter;
System.out.println("list " + list.getData().get(0).getQuote());
System.out.println("listSorter " + listSorter.get(0).getQuote());
System.out.println("cList " + cList.get(0).getQuote());
rcvMainAdp.notifyDataSetChanged();
}
#Override
public void onFailure(Call<cInfoPack> call, Throwable t) {
Toast.makeText(MainActivity.this, "onFailure", Toast.LENGTH_SHORT).show();
Log.d("XXXX", t.getLocalizedMessage());
call.cancel();
}
});
}
[Adapter]
public class rcvMainAdapter extends RecyclerView.Adapter<rcvMainAdapter.ViewHolder> {
private List<cData> idxCoin;
//ItemClickListener itemClickListener;
rcvMainAdapter(List<cData> data) {this.idxCoin = data;}
#NonNull
#NotNull
#Override
public ViewHolder onCreateViewHolder(#NonNull #NotNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.rcv_main,parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull #NotNull ViewHolder holder, int position) {
cData cdata = idxCoin.get(position);
TextView tvSym = holder.tvSymbol;
tvSym.setText(cdata.getSymbol());
TextView tvQuo = holder.tvQuote;
BigDecimal tvQuote_BD = new BigDecimal(cdata.getQuote().getuSD().getPrice().toString());
tvQuote_BD.setScale(6, RoundingMode.DOWN);
tvQuo.setText(tvQuote_BD.toString());
TextView tvV24 = holder.tvVolume24;
BigDecimal tvVolume24_BD = new BigDecimal(cdata.getQuote().getuSD().getVolume24h().toString());
BigInteger tvVolume24_BI = tvVolume24_BD.toBigInteger();
tvV24.setText(tvVolume24_BI.toString());
}
#Override
public int getItemCount() {
return idxCoin.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvSymbol, tvQuote, tvVolume24;
public ViewHolder(#NonNull #NotNull View itemView) {
super(itemView);
tvSymbol = itemView.findViewById(R.id.tvSymbol);
tvQuote = itemView.findViewById(R.id.tvQuote);
tvVolume24 = itemView.findViewById(R.id.tvVolume24);
//itemView.setOnClickListener(this);
}
}
/*
public interface ItemClickListener{
void onItemClick(View view, int position);
}
*/
}
PS: apologies for the rubbish coding as this is self taught and modifying some codes found online.
Remove this in response.
cList.clear();
Add This line in response
rcvMainAdp.setdata(listSorter);
In rcvMainAdp Adapter, Create a Method setdata()
public void setdata(ArrayList<cData> data) {
this.idxCoin = data;
notifyDataSetChanged();
}
Problem most likely is that when you call initRCV_Main() You set the adapter to the list as in rcvMainAdp = new rcvMainAdapter(cList); And when list is changed and you set it to adapter it functions.
But when you call getCoinData() and rcvMainAdp.notifyDataSetChanged(); at the end you never set the changed list to the adapter until you click initRCV_Main() again.
So maybe the fix is calling rcvMainAdp = new rcvMainAdapter(cList) and then
rcvMainAdp.notifyDataSetChanged();

How can I reload/refresh the RecyclerView after deleting a item

I have already tried many solution from this site. But still does not get the working solution.
This is my Fragment class. I have set the Adpater in this class.
public class FeedFragment extends Fragment {
RecyclerView recyclerView;
Context context;
FloatingActionButton addFeedButton;
private ArrayList<Feed> feeds;
FeedService feedService;
FeedRecyclerViewAdapter feedRecyclerViewAdapter;
TextView noDataTextView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_feed, container, false);
noDataTextView = view.findViewById(R.id.no_data_textView);
addFeedButton = view.findViewById(R.id.feed_floating_button);
System.out.println(getRole());
if (getRole().equals("ROLE_ADMIN")) {
addFeedButton.setVisibility(View.VISIBLE);
} else {
addFeedButton.setVisibility(View.GONE);
}
addFeedButton.setOnClickListener(v -> {
AddFeedFragment addFeedFragment = new AddFeedFragment();
FragmentManager fragmentManager = Objects.requireNonNull(getActivity()).getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_for_fragments, addFeedFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
});
recyclerView = view.findViewById(R.id.feedRecyclerView);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
initializeData();
return view;
}
public void initializeData() {
feedService = APIUtils.getFeedService();
feedService.getFeeds(AuthenticationToken()).enqueue(new Callback<List<Feed>>() {
#Override
public void onResponse(Call<List<Feed>> call, Response<List<Feed>> response) {
if (response.isSuccessful()) {
if (response != null) {
feeds = new ArrayList<>(response.body());
if(feeds.isEmpty()){
noDataTextView.setVisibility(View.VISIBLE);
}
else {
feedRecyclerViewAdapter = new FeedRecyclerViewAdapter(getActivity(), feeds);
recyclerView.setAdapter(feedRecyclerViewAdapter);
}
}
} else {
Toast.makeText(getContext(), "Unauthorized", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<List<Feed>> call, Throwable t) {
Toast.makeText(getContext(), t.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
private String AuthenticationToken() {
PrefManager prefManager = new PrefManager(getContext());
return prefManager.Authorization();
}
private String getRole() {
PrefManager prefManager = new PrefManager(getContext());
return prefManager.getRole();
}
}
And this is my Adapter class.
public class FeedRecyclerViewAdapter extends RecyclerView.Adapter<FeedRecyclerViewAdapter.FeedViewHolder> {
private ArrayList<Feed> feeds;
private Context context;
FeedService feedService;
ProfileService profileService;
public FeedRecyclerViewAdapter(Context context, ArrayList<Feed> feeds) {
this.feeds = feeds;
this.context = context;
}
public static class FeedViewHolder extends RecyclerView.ViewHolder {
CardView feedCardView;
TextView textViewTitle, textViewDescription, textViewPostBy, textViewPostDate, textViewMobile;
TextView textViewOption;
ImageView imageView,callButtonView;
public FeedViewHolder(#NonNull #NotNull View itemView) {
super(itemView);
feedCardView = itemView.findViewById(R.id.feedCardView);
imageView=itemView.findViewById(R.id.user_photo);
callButtonView=itemView.findViewById(R.id.callButton);
textViewTitle = itemView.findViewById(R.id.feedTitle);
textViewDescription = itemView.findViewById(R.id.feedDescription);
textViewPostBy = itemView.findViewById(R.id.postBy);
textViewPostDate = itemView.findViewById(R.id.posDate);
textViewMobile = itemView.findViewById(R.id.mobile);
textViewOption = itemView.findViewById(R.id.three_dot);
}
}
#NonNull
#NotNull
#Override
public FeedRecyclerViewAdapter.FeedViewHolder onCreateViewHolder(#NonNull #NotNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_custom_layout, parent, false);
FeedViewHolder fvh = new FeedViewHolder(view);
return fvh;
}
#Override
public void onBindViewHolder(#NonNull #NotNull FeedViewHolder holder, int position) {
final long itemId = feeds.get(position).getId();
final String profilePicName=feeds.get(position).getUser().getProfile().getProfilePic();
profileService= APIUtils.getProfileService();
profileService.loadProfile(AuthenticationToken(),profilePicName).enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
System.out.println(response.code());
if(response.isSuccessful()){
try {
byte[] bytes=response.body().bytes();
Bitmap bitmap= BitmapFactory.decodeByteArray(bytes,0,bytes.length);
Glide.with(context).asBitmap()
.load(bitmap)
.apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL))
.placeholder(R.drawable.account_circle).into(holder.imageView);
} catch (IOException e) {
e.printStackTrace();
}
}
else{
Toast.makeText(context,"Load failed",Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(context,t.getMessage(),Toast.LENGTH_LONG).show();
}
});
holder.textViewTitle.setText(feeds.get(position).getFeedTitle());
holder.textViewDescription.setText(feeds.get(position).getFeedDescription());
holder.textViewPostBy.setText(feeds.get(position).getUser().getFullName());
holder.textViewPostDate.setText(feeds.get(position).getPostDate());
holder.textViewMobile.setText(feeds.get(position).getUser().getMobile());
holder.callButtonView.setOnClickListener(v -> {
String phone=feeds.get(position).getUser().getMobile();
String dialCall="tel:"+phone;
Intent intent=new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse(dialCall));
context.startActivity(intent);
});
ItemAnimation.animateFadeIn(holder.itemView, position);
if(getRole().equals("ROLE_ADMIN")){
holder.textViewOption.setOnClickListener(v -> {
PopupMenu popupMenu = new PopupMenu(context, holder.textViewOption);
popupMenu.inflate(R.menu.update_delete_menu);
popupMenu.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case R.id.popup_update:
AlertDialog.Builder builder= new AlertDialog.Builder(v.getContext());
builder.setTitle(R.string.dialog_feed_update_title);
builder.setPositiveButton(R.string.dialog_yes, (dialog, which) -> {
Intent intent = new Intent(context, FeedUpdateActivity.class);
intent.putExtra("feedId", itemId);
context.startActivity(intent);
});
builder.setNegativeButton(R.string.dialog_no, (dialog, which) -> {
Toast.makeText(context.getApplicationContext(),"Canceled",Toast.LENGTH_LONG).show();
});
builder.create().show();
break;
case R.id.popup_delete:
AlertDialog.Builder builder1 = new AlertDialog.Builder(v.getContext());
builder1.setTitle(R.string.dialog_delete_title);
builder1.setPositiveButton(R.string.dialog_yes, (dialog, which) -> {
feedService = APIUtils.getFeedService();
feedService.deleteFeed(itemId, AuthenticationToken()).enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
Toast.makeText(context.getApplicationContext(), "Deleted", Toast.LENGTH_LONG).show();
notifyDataSetChanged();
} else {
Toast.makeText(context.getApplicationContext(), "Delete Failed", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(context.getApplicationContext(), t.getMessage(), Toast.LENGTH_LONG).show();
}
});
});
builder1.setNegativeButton(R.string.dialog_no, (dialog, which) -> {
Toast.makeText(context.getApplicationContext(), "Canceled", Toast.LENGTH_LONG).show();
});
builder1.create().show();
break;
}
return false;
});
popupMenu.show();
});
}
else{
holder.textViewOption.setVisibility(View.GONE);
}
}
#Override
public void onAttachedToRecyclerView(#NotNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public int getItemCount() {
return feeds.size();
}
private String AuthenticationToken() {
PrefManager prefManager = new PrefManager(context.getApplicationContext());
return prefManager.Authorization();
}
private String getRole() {
PrefManager prefManager = new PrefManager(context.getApplicationContext());
return prefManager.getRole();
}
}
Here I have called the notifyDataSetChange. But it can not refresh the arraylist set in the Fragment class. How can I refresh that arraylist in fragment after the deletion is completed in Adapter class.
You can use DiffUtil to load data into the recyclerview adapter. For the on click listener you can implement that method in the fragment itself(create interface in the adapter class, implement method in fragment, and pass instance of the interface to the adapter's constructor). Now you can manipulate the data as much as you want by changing the original list.

Cannot Save RecyclerView Position in Fragment

I have read several threads on approaches to save the position of a RecyclerView. I have implemented the below, however it does not appear to be saving the position on either screen rotation or back navigation, it simply loads back to the top of the RecyclerView:
public class FeedFragment 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 static final String POLL_QUESTION = "POLL_QUESTION";
private static final String POLL_IMAGE_URL = "POLL_IMAGE_URL";
private static final String FILTER_ACTION = "UPDATE_WIDGET";
private static final String POLL_ID = "POLL_ID";
private static final String RECYCLERVIEW_STATE = "Recyclerview_State";
private Parcelable mRecyclerViewState;
private static Bundle mRecyclerViewBundle;
private MyReceiver myReceiver;
#BindView(R.id.list)
RecyclerView mRecyclerview;
private SharedPreferences mPrefs;
private SharedPreferences.Editor editor;
private DatabaseReference mBaseRef;
private DatabaseReference mPollsRef;
private LinearLayoutManager mLayoutManager;
private FirebaseRecyclerAdapter<Poll, PollHolder> mFireAdapter;
private OnFragmentInteractionListener mListener;
public FeedFragment() {
// 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 FeedFragment.
*/
// TODO: Rename and change types and number of parameters
public static FeedFragment newInstance(String param1, String param2) {
FeedFragment fragment = new FeedFragment();
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);
if (getArguments() != null) {
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_poll_feed, container, false);
ButterKnife.bind(this, v);
mPrefs = getActivity().getSharedPreferences("MyPrefs", Context.MODE_PRIVATE);
editor = mPrefs.edit();
if (savedInstanceState != null) {
mRecyclerViewState = savedInstanceState.getParcelable(RECYCLERVIEW_STATE);
}
mRecyclerview.getItemAnimator().setChangeDuration(0);
mLayoutManager = new LinearLayoutManager(getContext());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
mRecyclerview.setSaveEnabled(true);
mRecyclerview.setLayoutManager(mLayoutManager);
setReceiver();
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
// #Override
// public void onSaveInstanceState(#NonNull Bundle outState) {
// super.onSaveInstanceState(outState);
// mRecyclerViewState = mLayoutManager.onSaveInstanceState();
// outState.putParcelable(RECYCLERVIEW_STATE, mRecyclerViewState);
// }
//
//
// #Override
// public void onViewStateRestored(#Nullable Bundle savedInstanceState) {
// super.onViewStateRestored(savedInstanceState);
// if (savedInstanceState != null){
// mRecyclerViewState = savedInstanceState.getParcelable(RECYCLERVIEW_STATE);
// }
// }
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
mRecyclerViewState = mLayoutManager.onSaveInstanceState();
outState.putParcelable(RECYCLERVIEW_STATE, mRecyclerViewState);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null){
mRecyclerViewState = savedInstanceState.getParcelable(RECYCLERVIEW_STATE);
}
}
#Override
public void onResume() {
super.onResume();
if (mRecyclerViewState != null){
mLayoutManager.onRestoreInstanceState(mRecyclerViewState);
}
}
#Override
public void onStart() {
super.onStart();
Query query = FirebaseDatabase.getInstance()
.getReference()
.child("Polls");
FirebaseRecyclerOptions<Poll> options = new FirebaseRecyclerOptions.Builder<Poll>()
.setQuery(query, Poll.class)
.build();
mFireAdapter = new FirebaseRecyclerAdapter<Poll, PollHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final PollHolder holder, int position, #NonNull Poll model) {
holder.mPollQuestion.setText(model.getQuestion());
String voteCount = String.valueOf(model.getVote_count());
//Update shared prefs with latest question
editor.putString(POLL_QUESTION, model.getQuestion());
editor.putString(POLL_IMAGE_URL, model.getImage_URL());
editor.apply();
//TODO: Investigate formatting of vote count for thousands
holder.mVoteCount.setText(voteCount);
Picasso.get()
.load(model.getImage_URL())
.fit()
.into(holder.mPollImage);
//TODO: Cannot understand how to utilize IntentService to update widget
//TODO: Followed this tutorial: https://www.journaldev.com/20735/android-intentservice-broadcastreceiver
Intent intent = new Intent(getContext(), MyService.class);
intent.putExtra(POLL_QUESTION, model.getQuestion());
intent.putExtra(POLL_IMAGE_URL, model.getImage_URL());
getActivity().startService(intent);
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String pollID = mFireAdapter.getRef(holder.getAdapterPosition()).getKey();
if (getActivity().findViewById(R.id.two_pane_constraint_layout) != null & getActivity().getApplication().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
FragmentManager fm = getActivity().getSupportFragmentManager();
PollFragment pollFragment = PollFragment.newInstance(pollID);
fm.beginTransaction()
.replace(R.id.poll_fragment, pollFragment)
.commit();
} else {
Intent i = new Intent(getActivity().getApplicationContext(), PollHostActivity.class);
i.putExtra(POLL_ID, pollID);
startActivity(i);
}
}
});
}
#Override
public PollHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.latest_item, parent, false);
return new PollHolder(v);
}
};
mRecyclerview.setAdapter(mFireAdapter);
scrollToPosition();
mFireAdapter.startListening();
}
public static class PollHolder extends RecyclerView.ViewHolder {
TextView mPollQuestion;
TextView mVoteCount;
ImageView mPollImage;
View mView;
String mTag;
public PollHolder(View itemView) {
super(itemView);
mPollQuestion = itemView.findViewById(R.id.latest_item_question);
mPollImage = itemView.findViewById(R.id.pollThumbNailImage);
mVoteCount = itemView.findViewById(R.id.latest_item_poll_count);
this.mView = itemView;
}
public void setTag(String tag) {
this.mTag = tag;
}
public View getViewByTag(String tag) {
return mView;
}
}
private void setReceiver() {
myReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(FILTER_ACTION);
// LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, intentFilter);
}
private void scrollToPosition() {
mFireAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int pollCount = mFireAdapter.getItemCount();
int lastVisiblePosition = mLayoutManager.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 >= (pollCount - 1) && lastVisiblePosition == (positionStart - 1))) {
mRecyclerview.scrollToPosition(positionStart);
}
}
});
}
private class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String poll_Question = intent.getStringExtra("broadcastMessage");
//TODO: Update Widget - used answer from https://stackoverflow.com/questions/3455123/programmatically-update-widget-from-activity-service-receiver
int[] ids = AppWidgetManager.getInstance(getContext()).getAppWidgetIds(new ComponentName(getContext(), PollWidgetProvider.class));
PollWidgetProvider pollWidgetProvider = new PollWidgetProvider();
pollWidgetProvider.onUpdate(getContext(), AppWidgetManager.getInstance(getContext()), ids);
}
}
/**
* 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);
}
}
EDIT:
I am trying to save within a Fragment, that is attached to a host Activity. I have some RecyclerView functionality coded to on.Start(), which may be overriding the methods below.
I also feel I need to make a call to onPause() somewhere since the RecyclerView is located inside a Fragment.
Full code available:https://github.com/troy21688/LiveVotingUdacity

How can i pass a string value from recyclerview adapter to fragment

I want to pass a string value from my adapter class to my fragment. I tried storing the string in a bundle. To retrieve the value i used Bundle b = getArguments(); b.getString("key") the problem is im getting a null pointer exception. Below is the code that saves the string in a bundle. So my question is how can i pass a string value from adapterA to fragmentB.
Thanks in advance.
Adapter.java
public class ToDoRecyclerViewAdapter extends RecyclerView.Adapter<ToDoRecyclerViewAdapter.ViewHolder> {
private Context context;
private List<Aktivnost_> mValues;
private final OnListFragmentInteractionListener mListener;
public ToDoRecyclerViewAdapter td;
public ToDoRecyclerViewAdapter(List<Aktivnost_ > items, Context context, OnListFragmentInteractionListener listener) {
mValues = items;
mListener = listener;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fragment_todo, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.mItem = mValues.get(position);
holder.mContentView.setText(mValues.get(position).getNaziv());
holder.mDateView.setText(mValues.get(position).getDatum());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (null != mListener) {
mListener.onListFragmentInteraction(holder.mItem);
Intent i = new Intent(context.getApplicationContext(), PodrobnostiActivity.class);
i.putExtra("task_id", mValues.get(position).getId_());
context.getApplicationContext().startActivity(i);
Toast.makeText(v.getContext(), "task - " + mValues.get(position).getId_(), Toast.LENGTH_SHORT).show();
}
}
});
holder.mView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(final View v) {
AlertDialog.Builder adb = new AlertDialog.Builder(v.getContext());
CharSequence meni[] = new CharSequence[] {"DOING", "FINISHED"};
adb.setItems(meni, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if(i == 0) {
Bundle b = new Bundle();
DoingFragment d = new DoingFragment();
mValues.get(i).setStanje("doing");
b.putString("doing", mValues.get(i).getStanje());
d.setArguments(b);
} else {
mValues.get(i).setStanje("koncano");
}
}
});
AlertDialog alertDialog = adb.create();
alertDialog.setCancelable(true);
alertDialog.show();
return true;
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mContentView;
public final TextView mDateView;
public long id;
public Aktivnost_ mItem;
public ViewHolder(View view) {
super(view);
mView = view;
this.id = id;
mDateView = (TextView) view.findViewById(R.id.Date);
mContentView = (TextView) view.findViewById(R.id.content);
}
#Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}
And i want to get the value i set in bundle in this fragment.
Fragment.java
public class DoingFragment extends Fragment {
DoingFragmentRecyclerViewAdapter mAdapter;
private OnListFragmentInteractionListener mListener;
public DoingFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_doingfragment_list, container, false);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.list_doing);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL));
mAdapter = new DoingFragmentRecyclerViewAdapter(listAktivnosti(),mListener);
recyclerView.setAdapter(mAdapter);
return view;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnListFragmentInteractionListener) {
mListener = (OnListFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnListFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnListFragmentInteractionListener {
void onListFragmentInteraction1(Aktivnost_ item);
}
AppDatabase db;
public void openDB() {
db = new AppDatabase(getContext());
db.open();
}
Aktivnost_ ak;
List<Aktivnost_> array;
public List<Aktivnost_> listAktivnosti() {
array = new ArrayList<>();
openDB();
Bundle b = getArguments();
Cursor cursor = db.getAllRows(b.getString("doing"));
while(cursor.moveToNext()) {
ak = new Aktivnost_();
ak.setId_(cursor.getLong(cursor.getColumnIndex("_id")));
ak.setNaziv(cursor.getString(cursor.getColumnIndex("naziv")));
ak.setDatum(cursor.getString(cursor.getColumnIndex("datum")));
ak.setFk_projekt(cursor.getInt(cursor.getColumnIndex("fk_projekt")));
ak.setUdeleženci(cursor.getString(cursor.getColumnIndex("udelezenci")));
ak.setStanje(cursor.getString(cursor.getColumnIndex("stanje")));
array.add(ak);
}
return array;
}
}
From the code, I can see you are only setting the Bundle parameters in Fragment object, but not using that fragment object further.
You need to display that fragment object first, then it will reflect into your target fragment.

Categories