Recyclerview with set visibility - android

I have a expense request kind of thing for my admin app. What i want to achieve is when the user clicks the approve button, the text on it should get changed to Approved and reject button should disappear and vice versa.
I am unable to achieve this, I have tried everything but getting even weirder outputs with each attempt to fix this. Please attach a reason with your changes as it would help me. Thanks
This is my code
package com.emlocks.timeaccess;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
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.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class Expenses extends AppCompatActivity {
NetworkController networkController;
Bundle ss;
private SharedPreferences prefs;
List<ExpenseP> expensep = new ArrayList<>();
RecyclerView rvRegs;
Gson gson = new Gson();
HashMap<Integer, String> hmap = new HashMap<>();
public static final String TAG = "Expenses";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_expenses);
ss = savedInstanceState;
networkController = RetrofitClientInstance.getRetrofitInstance().create(NetworkController.class);
prefs = getSharedPreferences(getResources().getString(R.string.prefs), MODE_PRIVATE);
rvRegs = findViewById(R.id.rvExpense);
networkController = RetrofitClientInstance.getRetrofitInstance().create(NetworkController.class);
networkController.getexpense("Bearer " + prefs.getString("token", null), prefs.getString("email", null)).enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if (response.code() == 200) {
JsonArray array = response.body().getAsJsonArray("data");
System.out.println(array);
Log.d(TAG, "onResponse: " + array);
for (JsonElement j :
array) {
expensep.add(gson.fromJson(j, ExpenseP.class));
}
rvRegs.setAdapter(new ExpenseAdapter());
rvRegs.setLayoutManager(new LinearLayoutManager(Expenses.this));
} else {
Log.d(TAG, "onResponse: Unsuccessful" + response.errorBody());
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.d(TAG, "onFailure: " + t.getMessage());
Log.d(TAG, "onFailure: " + t.getStackTrace());
Log.d(TAG, "onFailure: " + t.getLocalizedMessage());
}
});
}
class ExpenseAdapter extends RecyclerView.Adapter<ExpenseAdapter.VH> {
#NonNull
#Override
public VH onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return new VH(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_expense, viewGroup, false));
}
#Override
public void onBindViewHolder(#NonNull final VH vh, int i) {
final ExpenseP ex = expensep.get(i);
vh.etFN.setText(ex.getUserId().split("-")[1]);
vh.etnm.setText(ex.getDate());
vh.etnm1.setText(ex.getAmount());
vh.leaves.setText(ex.getRemark());
vh.u_name.setText(ex.getName());
vh.u_department.setText(ex.getDepName());
if (ex.getStatus() == null) {
View.OnClickListener approveRejectClickListner = new View.OnClickListener() {
#Override
public void onClick(View v) {
int status = 0;
switch (v.getId()) {
case R.id.btnApprove:
status = 1;
vh.btnReject.setEnabled(true);
break;
case R.id.btnReject:
status = 0;
vh.btnApprove.setEnabled(true);
break;
}
JsonObject body = new JsonObject();
body.add("expense_id", new JsonPrimitive(ex.getExpenseId()));
body.add("status", new JsonPrimitive(status));
body.add("user_id", new JsonPrimitive(ex.getUserId()));
networkController.patchexpense("Bearer " + prefs.getString("token", null), prefs.getString("email", null), body).enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if (response.code() == 200) {
Toast.makeText(Expenses.this, "Success", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
}
});
if(vh.btnApprove.isPressed()==true)
{
vh.btnApprove.setVisibility(View.GONE);
}
else if (vh.btnReject.isPressed()==true){
vh.btnReject.setVisibility(View.GONE);
}
}
};
vh.btnApprove.setOnClickListener(approveRejectClickListner);
vh.btnReject.setOnClickListener(approveRejectClickListner);
}
else
if (ex.getStatus() != 1) {
vh.btnReject.setText("Rejected");
vh.btnApprove.setVisibility(View.VISIBLE);
} else {
vh.btnApprove.setText("Approved");
vh.btnReject.setVisibility(View.VISIBLE);
}
}
#Override
public int getItemCount() {
return expensep.size();
}
class VH extends RecyclerView.ViewHolder {
TextView etFN, etnm, etnm1, leaves,u_name,u_department;
Button btnApprove, btnReject;
public VH(#NonNull View itemView) {
super(itemView);
etFN = itemView.findViewById(R.id.U_code);
etnm = itemView.findViewById(R.id.date);
etnm1 = itemView.findViewById(R.id.type);
leaves = itemView.findViewById(R.id.msg);
u_name=itemView.findViewById(R.id.U_name);
u_department=itemView.findViewById(R.id.U_dep);
btnApprove = itemView.findViewById(R.id.btnApprove);
btnReject = itemView.findViewById(R.id.btnReject);
}
}
}
}

One approach to do this would be to utilize multiple ViewHolders and corresponding view types.
When a user approves an item, you handle that approval click by updating the item in question, and then utilizing notifyItemChanged(getAdapterPosition()) to tell the Adapter that the item has changed.
You can override getItemViewType and have it return a layout depending on it's state. For example:
abstract class BaseViewHolder extends ViewHolder {
// Protected common views, like name, etc.
BaseViewHolder(View itemView) {
super(itemView);
// set up common views
}
public final void bindTo(ExpenseP expense) {
// set up common views
onBind(expense);
}
protected abstract void onBind(ExpenseP expense);
}
class AcceptedExpenseViewHolder extends BaseViewHolder {
// Protected accepted-only views...
BaseViewHolder(View itemView) {
super(itemView);
// set up accepted-only views...
}
#Override
protected void onBind(ExpenseP expense) {
// bind accepted-only views...
}
}
// Another class for RejectedExpenseViewHolder
// Another class for DefaultExpenseViewHolder (neither accepted or rejected)
Then, define a layout for each. Android IDs don't have to be globally unique. We can leverage this by utilizing the same id for common fields. For example, where we want the name to go is always R.id.expense_name or whatever.
accepted_expense_item.xml
rejected_expense_item.xml
default_expense_item.xml
Each of these layouts will have a unique identifier, which we can utilize as the ViewType inside of getItemViewType and later in onCreateViewHolder, instead of specifying our own:
int getItemViewType(position) {
ExpenseP item = data.get(position);
if (item.getStatus() == null) return R.layout.default_expense_item;
// ... etc.
}
BaseViewHolder onCreateViewHolder(...) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(viewType, parent, false);
switch (viewType) {
case R.layout.accepted_expense_item:
return new AcceptedExpenseViewHolder(itemView)
// etc.
}
}
If you want to propagate clicks to update item state, you'd pass in some kind of listener to your ViewHolder, and update state appropriately when it's called. Then you can notify your adapter that a state change occurred. For example:
interface DefaultListener {
void onAccepted(int position);
void onRejected(int position);
}
class DefaultExpenseViewHolder extends BaseViewHolder {
// Protected default-only views...
BaseViewHolder(View itemView, DefaultListener listener) {
super(itemView);
Button accepted = findViewById(R.id.accepted);
accepted.setOnClickListener(v -> listener.onAccepted(getAdapterPosition()));
}
//...
}
This will propagate it up to wherever Listener is defined. For example, in the adapter's onCreateViewHolder you could have:
switch (viewType) {
case R.layout.accepted_expense_item:
return new AcceptedExpenseViewHolder(itemView, this)
}
And have Adapter implement the listener. You could then, when invoked, update the status appropriately and then notify the adapter that a change happened.
For example:
void onAccepted(int position) {
ExpenseP item = data.get(position);
networkControllerStuff.accept(item, response -> {
// Check status, and update appropriately.
// Remember to replace the item in data with an updated item.
// And then:
notifyItemChanged(position)
})
}
TL;DR There's more things here I can think to handle, but the general approach I'm trying to get across here is to use multiple viewtypes to your advantage here, instead of trying to manipulate some global view.

Related

How to use a ViewModel outside of onCreate()?

I have an Activity with a RecyclerView which display Livedata from a room database.
My aim is to start a new Activity with more data from the room database when the user is clicking on the corresponding item in the RecyclerView.
For that I overwrote the onClick() method in the adapter of the RecylcerView. Each object of the RecyclerView has a Id, I need that Id to get the corresponding data from the database. So I passed the Id from the Adapter to the Activity.
To search an element by Id in the database that I need the ViewModel object in the MainAcitivty. It is initialized in the onCreate() of the Activity. The method I called in the Adapter is outside the onCreate() and I get a null object reference exception when I try to use it.
How can I use the ViewModel outside of the onCreate() method of the Activity? Or is there another way to search for the element in the database?
Thank you!
The Adapter class:
In the onClick() method is the relevant part.
package com.example.fillmyplate.activities;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.fillmyplate.R;
import com.example.fillmyplate.entitys.Recipe;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
class RecipeAdapter extends RecyclerView.Adapter<RecipeAdapter.RecipeViewHolder> {
private static final String TAG = "RecipeAdapter";
private List<Recipe> mRecipes = new ArrayList<>();
private LayoutInflater mInflater;
private Context mContext;
private MainActivity mainActivity = new MainActivity();
private static int backGroundIndex = 0;
class RecipeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final TextView recipeTitleItemView;
ImageView imageView;
public RecipeViewHolder(View itemView) {
super(itemView);
recipeTitleItemView = itemView.findViewById(R.id.name);
imageView = itemView.findViewById(R.id.card_image_view);
Log.d(TAG, "RecipeViewHolder: index " + backGroundIndex);
if (backGroundIndex == 0) {
imageView.setImageResource(R.drawable.background_green);
backGroundIndex++;
} else if (backGroundIndex == 1 ) {
imageView.setImageResource(R.drawable.background_red);
backGroundIndex++;
} else if (backGroundIndex == 2 ) {
imageView.setImageResource(R.drawable.background_blue);
backGroundIndex = 0;
}
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
// This should be the mistake.
mainActivity.startKnownRecipeActivity(position);
}
}
public RecipeAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.mContext = context;
}
#NonNull
#Override
public RecipeAdapter.RecipeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
// Inflate an item view
View mRecipeTitleView = mInflater.inflate(
R.layout.recipe_list_row, parent, false);
return new RecipeViewHolder(mRecipeTitleView);
}
// Get data into the corrsponding views
#Override
public void onBindViewHolder(RecipeAdapter.RecipeViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: " + position);
Recipe currentRecipe = mRecipes.get(position);
Log.d(TAG, "onBindViewHolder: setText " + currentRecipe);
holder.recipeTitleItemView.setText(currentRecipe.getTitle());
}
#Override
public int getItemCount() {
return mRecipes.size();
}
public void setRecipes(List<Recipe> recipes) {
this.mRecipes = recipes;
Log.d(TAG, "setRecipes: notifydataChanged" );
notifyDataSetChanged();
}
}
MainActivity:
package com.example.fillmyplate.activities;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.media.Image;
import android.os.Build;
import android.os.Bundle;
import com.example.fillmyplate.R;
import com.example.fillmyplate.entitys.Recipe;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.cardview.widget.CardView;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainAcitivity";
private static final int NEW_RECIPE_ACTIVITY_REQUEST_CODE = 1;
private RecyclerView mRecyclerView;
private RecipeViewModel mRecipeViewmodel;
private RecyclerView.LayoutManager layoutManager;
//private final List<String> mTitleList = new LinkedList<>();
//NEU for adapter
private List<String> recipeDataList = new ArrayList<>();
RecipeRoomDatabase db;
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// RECYCLER VIEW STUFF
mRecyclerView = findViewById(R.id.recycler_view1);
mRecyclerView.setHasFixedSize(true);
// user linerar layout manager
layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
// specify an adapter
final RecipeAdapter recipeAdapter = new RecipeAdapter(this);
//mAdapter = new RecipeAdapter(this, mTitleList);
mRecyclerView.setAdapter(recipeAdapter);
mRecipeViewmodel = ViewModelProviders.of(this).get(RecipeViewModel.class);
mRecipeViewmodel.getAllRecipes().observe(this, new Observer<List<Recipe>>() {
#Override
public void onChanged(List<Recipe> recipes) {
Log.d(TAG, "onChanged: " + recipes.toString());
for (Recipe rec : recipes) {
Log.d(TAG, "onChanged: " + rec.getTitle());
Log.d(TAG, "onChanged: recipe id " + rec.getUid());
}
recipeAdapter.setRecipes(recipes);
}
});
// DB
db = Room.databaseBuilder(getApplicationContext(), RecipeRoomDatabase.class, "appdb").build();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddRecipeActivity.class);
startActivityForResult(intent, NEW_RECIPE_ACTIVITY_REQUEST_CODE);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: ");
if (requestCode == NEW_RECIPE_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
Log.d(TAG, "onActivityResult: " + data.getStringExtra(AddRecipeActivity.EXTRA_REPLY));
// mTitleList.add(data.getStringExtra(AddRecipeActivity.EXTRA_REPLY));
Recipe rec = new Recipe(data.getStringExtra(AddRecipeActivity.EXTRA_REPLY));
mRecipeViewmodel.insert(rec);
} else {
Toast.makeText(
getApplicationContext(),
"saved",
Toast.LENGTH_LONG).show();
}
}
public void startKnownRecipeActivity(int position) {
Log.d(TAG, "startKnownRecipeActivity: Position " + position);
LiveData<List<Recipe>> recipe = mRecipeViewmodel.findById(position);
if (recipe.getValue().size() > 1) {
Log.d(TAG, "startKnownRecipeActivity: Error database found more than one recipe.");
} else {
Log.d(TAG, "startKnownRecipeActivity: Start activity with recipe " + recipe.getValue().get(0).getTitle());
}
}
}
The thing you need to do is to use a call back to send position back to activity.
To make sure that view position is correct you need to override 3 functions in RecyclerView Adapter:
#Override
public int getItemCount() {
return filteredUsers.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
For the Callback just create an Interface:
public interface AdapterListener {
void onClick(int id);
void onClick(ViewModel object);
}
Make a method in your Recycler Adapter:
private AdapterListener adapterListener;
public void setAdapterListener(AdapterListener mCallback) {
this.adapterListener = mCallback;
}
Implement this Interface on your Activity then you will get both methods of the interface.
public class MainActivity extends AppCompatActivity implements AdapterListener{
Register the listener by calling the setAdapterListener method in your activity after the initialization of the RecyclerView
adapterObject.setAdapterListener(MainActivity.this);
Then the last thing you need to do is call interface method in your item onClickListener, where u can either pass the complete model or just the id of the model
adapterListener.onClick(modelObject.getId());
OR
adapterListener.onClick(modelObject);

android studio recyclerView with firestore

I have orders collection in firestore:
And I have Sellers collection and inside Sellers collection have another Fruits collection :
I want to get data in orders collection only orders collection fruit_ID equals Sellers/Fruits collection Document ID and add into recyclerview
Is it possible?
Activity class:
package com.example.freshbucket.Seller;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.widget.Toast;
import com.example.freshbucket.Adapter.OrdersSellerRecylerAdapter;
import com.example.freshbucket.Model.PlaceOrder;
import com.example.freshbucket.R;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QuerySnapshot;
import javax.annotation.Nullable;
import static android.support.constraint.Constraints.TAG;
public class SellerGetOrdersActivity extends AppCompatActivity {
String fid, pro;
private FirebaseAuth mAuth = FirebaseAuth.getInstance();
String user_id = mAuth.getCurrentUser().getUid();
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference orders = db.collection("Orders");
private CollectionReference sellers = db.collection("Sellers/"+user_id+"/Fruits");
private OrdersSellerRecylerAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seller_get_orders);
setupRecyclerView();
}
private void setupRecyclerView()
{
Query query =orders.orderBy("timestamp", Query.Direction.DESCENDING).whereEqualTo("fruit_ID",fid);
FirestoreRecyclerOptions<PlaceOrder> options = new FirestoreRecyclerOptions.Builder<PlaceOrder>().setQuery(query, PlaceOrder.class).build();
adapter = new OrdersSellerRecylerAdapter(options);
RecyclerView recyclerView = findViewById(R.id.ordersReView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
//swipe delete
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT| ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder viewHolder1) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int i) {
adapter.deleteItem(viewHolder.getAdapterPosition());
}
}).attachToRecyclerView(recyclerView);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
sellers.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot queryDocumentSnapshots, #Nullable FirebaseFirestoreException e) {
if (e != null) {
Log.d(TAG, "Error:" + e.getMessage());
} else {
for (DocumentSnapshot doc :queryDocumentSnapshots){
fid = doc.getId();
// pro = doc.getString("province");
// fid = doc.getString("fruit_ID");
Toast.makeText(SellerGetOrdersActivity.this, "Register error:" +fid , Toast.LENGTH_SHORT).show();
}
}
}
});
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
Adapter:
package com.example.freshbucket.Adapter;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import com.example.freshbucket.Model.PlaceOrder;
import com.example.freshbucket.R;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
public class OrdersSellerRecylerAdapter extends FirestoreRecyclerAdapter<PlaceOrder, OrdersSellerRecylerAdapter.OrdersSellerHolder> {
Context context;
public OrdersSellerRecylerAdapter(#NonNull FirestoreRecyclerOptions<PlaceOrder> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull final OrdersSellerHolder holder, int position, #NonNull final PlaceOrder model) {
holder.txtfruitname.setText(model.getName());
holder.txtqun.setText(model.getQun());
holder.txtcusname.setText(model.getCustomer_Name());
holder.txtaddress1.setText(model.getAddressLine1());
holder.txtaddress2.setText(model.getAddressLine2());
holder.txtcity.setText(model.getCity());
}
#NonNull
#Override
public OrdersSellerHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.order_list_item_seller,viewGroup, false);
context = viewGroup.getContext();
return new OrdersSellerHolder(v);
}
class OrdersSellerHolder extends RecyclerView.ViewHolder{
TextView txtfruitname, txtqun, txtcusname, txtaddress1, txtaddress2, txtcity;
EditText tctBprice;
public OrdersSellerHolder(#NonNull View itemView) {
super(itemView);
txtfruitname = itemView.findViewById(R.id.fruitnametext);
txtqun = itemView.findViewById(R.id.fruitquntext);
txtcusname = itemView.findViewById(R.id.cusnametext);
txtaddress1 = itemView.findViewById(R.id.addres1text);
txtaddress2 = itemView.findViewById(R.id.addres2text);
txtcity = itemView.findViewById(R.id.citytext);
}
}
public void deleteItem(int position) {
getSnapshots().getSnapshot(position).getReference().delete();
}
}
I want to get data in orders collection only orders collection
fruit_ID
OK, you want to get fruit_ID?
equals Sellers/Fruits collection Document ID and add into recyclerview
and you want to get fruit_ID, which equals with Sellers/Fruits ?
like if (fruit_ID.equals(sellerFruits_ID) {// get fruit_ID}
I will try to answer it.
PROBLEM
1. you as a seller and have your seller uid in your Sellers collection and want to get V4x1Dh..
2. You have buyer uid in your Orders collection and want to get 83Fmf..
3. You want to get Banana in Sellers/Fruits, which the Banana as id.
Lastly, you want to load datas of Sellers/Fruits into recyclerView because
you want to get data in orders collection only orders collection
fruit_ID
ANSWER
Answer number one: Please retrieve the Sellers ids and get V4x1Dh based ViewHolder position that I will explain later.
Answer number two: Please retrieve the Orders ids and get 83Fmf based ViewHolder position that I will explain later.
Answer number two: Please retrieve the Sellers Fruits ids let's say sellerFruit_ID and get Banana based ViewHolder position that I will explain later. NOTE: Since Banana in document it will be id.
DETAILS:
Retrieving the Sellers ids and get V4x1Dh:
firebaseFirestore
.collection("Sellers")
.addSnapshotListener(new EventListener<QuerySnapshot>(){
#Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e){
for (DocumentChange doc : documentSnapshots.getDocumentChanges()){
if (doc.getType() == DocumentChange.Type.ADDED){
// RETRIEVING Orders id
String orders_ID = doc.getDocument().getId();
YourContentOrdersHere contentOrders = doc.getDocument().toObject(YourContentOrdersHere.class).withId(orders_ID);
// RETRIEVING Sellers id
String sellers_ID = doc.getDocument().getId();
YourContentSellersHere contentSellers = doc.getDocument().toObject(YourContentSellersHere.class).withId(sellers_ID);
contentListOrders.add(contentOrders); //example: List<YourContentOrdersHere> contentList
adapter.notifyDataSetChanged(); // before of course, you add this in onCreate adapterOrders = new YourAdapterOrders(contentListOrders);
contentListSellers.add(contents); //example: List<YourContentSellersHere> contentList
adapter.notifyDataSetChanged(); // before of course, you add this in onCreate adapterSellers = new YourAdapterSellers(contentListSellers);
}
}
}
});
make sure your content class extends the ids
public class YourContentOrdersHere extends OrdersId {
// make your constructor here of course
// make your getter to get id
}
and make OrdersId.class
public class OrdersId{
#Exclude
public String OrdersId;
public <T extends OrdersId> T withId(#NonNull final String id) {
this.OrdersId = id;
return (T) this;
}
}
and last one , from your adapter class retrieving OrdersId. As Example:
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// GET YOUR `Sellers` id based position and getSellerId() from getter of your content class
String sellers_ID = contentListSeller.get(position).getSellerId(); // don't forget List<YourContentSellers> contentList = new ArrayList<>();
firebaseFirestore
.collection("Sellers")
.document(sellers_ID)
.collection("Fruits")
.document("Banana")
// STORE 'LIKE TAP' USING LIKE BUTTON
holder.likeHome.seOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
/* RETRIEVING VALUE UNDER currentUserId */
firebaseFirestore.collection("Posts/" + postId + "/Likes").document(currentUserId).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>(){
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task){
if (!task.getResult().exists()) {
/* STORE NEW VALUE */
Map<String, Object> likesMap = new HashMap<>();
likesMap.put("timestamp", FieldValue.serverTimestamp);
firebaseFirestore.collection("Posts/" + postId + "/Likes").document(currentUserId).set(likesMap);
} else {
// retrieve like timestamp
String whenToLike = task.getResult().getString("timestamp");
holder.setWhenToLike(whenToLike);
/* DELETE VALUE */
firebaseFirestore.collection("Posts/" + postId + "/Likes").document(currentUserId).delete();
}
}
});
}
});
}

How to change TypeFace from BOLD to NORMAL once data updated on recyclerview adapter?

I'm working with Firebase data and RecyclerView Adapter.
The scenario is when user click the list, the initial status was UNREAD will be change to READ so the TypeFace should be change from BOLD to NORMAL.
My current back-end process to change the status from UNREAD to READ is working and updated to Firebase, however the interface of my specific RecyclerView item does not change from BOLD to NORMAL.
What I thought is no need to recall back the Firebase data in order to read the status but the interface should change based on user click.
Anyone can help me?
NotificationActivity.java:
package com.myapp.activity.notification;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
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.ValueEventListener;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.material.nereeducation.R;
import com.material.nereeducation.adapter.AdapterNotification;
import com.material.nereeducation.model.Notification;
import com.material.nereeducation.utils.Tools;
import com.material.nereeducation.widget.LineItemDecoration;
import java.util.ArrayList;
import java.util.List;
public class NotificationActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private AdapterNotification mAdapter;
private ActionModeCallback actionModeCallback;
private ActionMode actionMode;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
initToolbar();
initComponent();
Tools.setSystemBarColor(this, R.color.black);
}
private void initToolbar() {
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Notifications");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private List<Notification> items = new ArrayList<>();
private LinearLayout messageEmptyList;
private void initComponent() {
messageEmptyList = findViewById(R.id.messageEmptyList);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new LineItemDecoration(this, LinearLayout.VERTICAL));
recyclerView.setHasFixedSize(true);
//set data and list adapter
mAdapter = new AdapterNotification(this, items);
recyclerView.setAdapter(mAdapter);
mAdapter.setOnClickListener(new AdapterNotification.OnClickListener() {
#Override
public void onItemClick(View view, Notification obj, int pos) {
if (mAdapter.getSelectedItemCount() > 0) {
enableActionMode(pos);
} else {
// read the inbox which removes bold from the row
Notification notification = mAdapter.getItem(pos);
Toast.makeText(getApplicationContext(), "Read: " + notification.sender_id, Toast.LENGTH_SHORT).show();
updateStatus(notification.notificationId,"read",pos);
}
}
#Override
public void onItemLongClick(View view, Notification obj, int pos) {
enableActionMode(pos);
}
});
actionModeCallback = new ActionModeCallback();
getNotificationData();
}
private void getNotificationData()
{
items.clear();
GsonBuilder builder = new GsonBuilder();
final Gson gson = builder.create();
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
String uuid = firebaseAuth.getUid();
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference databaseReference = firebaseDatabase.getReference();
databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.getValue() != null)
{
for(DataSnapshot snapshot: dataSnapshot.getChildren())
{
String dataReceived = gson.toJson(snapshot.getValue());
Notification notificationItems = gson.fromJson(dataReceived, Notification.class);
items.add(notificationItems);
}
mAdapter.notifyDataSetChanged();
}else
{
messageEmptyList.setVisibility(View.VISIBLE);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void updateStatus(final String notificationId, String status, final int position) {
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
String uuid = firebaseAuth.getUid();
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference databaseReference = firebaseDatabase.getReference();
databaseReference.child("notifications/"+uuid+"/data_notification").child(notificationId).child("status").setValue(status
).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
mAdapter.notifyItemChanged(position); //Problem here - how to update text from BOLD to NORMAL for this item?
}
});
}
private void enableActionMode(int position) {
if (actionMode == null) {
actionMode = startSupportActionMode(actionModeCallback);
}
toggleSelection(position);
}
private void toggleSelection(int position) {
mAdapter.toggleSelection(position);
int count = mAdapter.getSelectedItemCount();
if (count == 0) {
actionMode.finish();
} else {
actionMode.setTitle(String.valueOf(count));
actionMode.invalidate();
}
}
private class ActionModeCallback implements ActionMode.Callback {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.menu_delete, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_delete) {
deleteInboxes();
mode.finish();
return true;
}
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
mAdapter.clearSelections();
actionMode = null;
}
}
private void deleteInboxes() {
List<Integer> selectedItemPositions = mAdapter.getSelectedItems();
for (int i = selectedItemPositions.size() - 1; i >= 0; i--) {
mAdapter.removeData(selectedItemPositions.get(i));
}
mAdapter.notifyDataSetChanged();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
} else {
Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
}
AdapterNotification.java:
package com.myapp.adapter;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.support.v7.widget.RecyclerView;
import android.text.format.DateUtils;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.material.nereeducation.R;
import com.material.nereeducation.helper.AlphabetColor;
import com.material.nereeducation.model.Notification;
import com.material.nereeducation.utils.Tools;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class AdapterNotification extends RecyclerView.Adapter<AdapterNotification.ViewHolder> {
private Context ctx;
private List<Notification> items;
private OnClickListener onClickListener = null;
private SparseBooleanArray selected_items;
private int current_selected_idx = -1;
private AlphabetColor alphabetColor;
public void setOnClickListener(OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView from, title, message, date, image_letter;
public ImageView image;
public RelativeLayout lyt_checked, lyt_image;
public View lyt_parent;
public ViewHolder(View view) {
super(view);
from = view.findViewById(R.id.from);
title = view.findViewById(R.id.title);
message = view.findViewById(R.id.message);
date = view.findViewById(R.id.date);
image_letter = view.findViewById(R.id.image_letter);
image = view.findViewById(R.id.image);
lyt_checked = view.findViewById(R.id.lyt_checked);
lyt_image = view.findViewById(R.id.lyt_image);
lyt_parent = view.findViewById(R.id.lyt_parent);
}
}
public AdapterNotification(Context mContext, List<Notification> items) {
this.ctx = mContext;
this.items = items;
selected_items = new SparseBooleanArray();
alphabetColor = new AlphabetColor(mContext);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_notification, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Notification notification = items.get(position);
// displaying text view data
System.out.println("sender type:"+notification.sender_type);
Character firstLetter;
if(notification.sender_type.equals("1")) //Admin
{
String admin = ctx.getString(R.string.admin_name);
holder.from.setText(admin);
firstLetter = admin.substring(0, 1).charAt(0);
holder.image_letter.setText(String.valueOf(firstLetter));
}else
{
holder.from.setText(notification.senderName);
firstLetter = notification.senderName.substring(0, 1).charAt(0);
holder.image_letter.setText(String.valueOf(firstLetter));
}
if(notification.status.equals("unread"))
{
holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
}
holder.title.setText(notification.title);
holder.message.setText(notification.message);
holder.date.setText(getDate(Long.parseLong(notification.date)));
holder.lyt_parent.setActivated(selected_items.get(position, false));
holder.lyt_parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (onClickListener == null) return;
onClickListener.onItemClick(v, notification, position);
}
});
holder.lyt_parent.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (onClickListener == null) return false;
onClickListener.onItemLongClick(v, notification, position);
return true;
}
});
toggleCheckedIcon(holder, position);
displayImage(holder, notification, firstLetter);
}
private void displayImage(ViewHolder holder, Notification notification, Character firstLetter) {
if (notification.image != null) {
Tools.displayImageRound(ctx, holder.image, notification.image);
holder.image.setColorFilter(null);
holder.image_letter.setVisibility(View.GONE);
} else {
holder.image.setImageResource(R.drawable.shape_circle);
holder.image.setColorFilter(alphabetColor.getColorByAlphabet(firstLetter), PorterDuff.Mode.MULTIPLY);
holder.image_letter.setVisibility(View.VISIBLE);
}
}
private String getDate(long time) {
Date date = new Date();
long currentTime = date.getTime();
String result = (String) DateUtils.getRelativeTimeSpanString(time, currentTime, 0);
return result;
}
private void toggleCheckedIcon(ViewHolder holder, int position) {
if (selected_items.get(position, false)) {
holder.lyt_image.setVisibility(View.GONE);
holder.lyt_checked.setVisibility(View.VISIBLE);
if (current_selected_idx == position) resetCurrentIndex();
} else {
holder.lyt_checked.setVisibility(View.GONE);
holder.lyt_image.setVisibility(View.VISIBLE);
if (current_selected_idx == position) resetCurrentIndex();
}
}
public Notification getItem(int position) {
return items.get(position);
}
#Override
public int getItemCount() {
return items.size();
}
public void toggleSelection(int pos) {
current_selected_idx = pos;
if (selected_items.get(pos, false)) {
selected_items.delete(pos);
} else {
selected_items.put(pos, true);
}
notifyItemChanged(pos);
}
public void clearSelections() {
selected_items.clear();
notifyDataSetChanged();
}
public int getSelectedItemCount() {
return selected_items.size();
}
public List<Integer> getSelectedItems() {
List<Integer> items = new ArrayList<>(selected_items.size());
for (int i = 0; i < selected_items.size(); i++) {
items.add(selected_items.keyAt(i));
}
return items;
}
public void removeData(int position) {
items.remove(position);
resetCurrentIndex();
}
private void resetCurrentIndex() {
current_selected_idx = -1;
}
public interface OnClickListener {
void onItemClick(View view, Notification obj, int pos);
void onItemLongClick(View view, Notification obj, int pos);
}
}
You need to handle ELSE too for this condition
if(notification.status.equals("unread")){
holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
}else{
holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
}
if you want to set textview different typeface or color in adapter you need to check for every position so in your case you only setting typeface bold for textview you have to set typeface again normal for default textview typeface.
Set your typeface Normal also in adapter.
set text default typeface Normal for textview like below.
holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
and then check item status for unread
if(notification.status.equals("unread")){
holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
}
So I guess your problem is that the state (read/unread) is applied on the database, but not reflected on the recycler view.
If this is the problem it is mainly because, you didnt handle the data change method of your list (and update it with the new values).
You are currently using this to get data:
databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {.....
This won't help you to control the item changed too.
Possible solution
A way solve it is to use (FirebaseUI) database instead of custom adapter.
FirebaseUI will listen to changes and update the list.
EDIT 2
use ChildEventListener instead of Listener For Single Value event
instead of this:
databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {.....
use this:
databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot) {.....
//add items to list (like you did)
#Override
public void onChildChanged(DataSnapshot dataSnapshot) {.....
//set the items again to the list (update them here) and notify
//data set changed (so values update in your list).
I believe you should set the font like this:
if ("unread".equals(notification.status)) {
holder.from.setTypeface(null, Typeface.BOLD);
holder.title.setTypeface(null, Typeface.BOLD);
} else {
holder.from.setTypeface(null, Typeface.NORMAL);
holder.title.setTypeface(null, Typeface.NORMAL);
}
The view is being reused by RecyclerView so once you set font to bold you need to set it back to normal next time it will be used.

How to add a button to Firebase Recycler view in Android?

I want to add a button for each item in the Firebase recycler view.
I've created the button, it's being showed, and i'm receiving the Toast when I press it.
But - How can I get the relevant item on it's list ?
For example - When I press the 'DELETE' I want to delete that certain mission 'aspodm'. (Sorry for the large picture, how do I make it smaller?)
This is how the database looks like (vfPvsk... is the user id, and 773f... is random uuid for mission id):
And that is the code of the relevant fragment. (The Toast when clicking the button is activated - I just don't know how to get to the relevant mission in order to delete it)
package com.airpal.yonatan.airpal;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
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.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
/**
* A simple {#link Fragment} subclass.
*/
public class PendingFragment_User extends Fragment {
private String TAG = "dDEBUG";
private RecyclerView mPendingList;
private DatabaseReference mMissionsDb;
private FirebaseAuth mAuth;
private String mCurrent_user_id;
private View mMainView;
Query queries;
public PendingFragment_User() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mMainView = inflater.inflate(R.layout.fragment_pending_user, container, false);
mPendingList = (RecyclerView)mMainView.findViewById(R.id.pending_recycler_user);
mAuth = FirebaseAuth.getInstance();
mCurrent_user_id = mAuth.getCurrentUser().getUid();
mMissionsDb = FirebaseDatabase.getInstance().getReference().child("Missions").child(mCurrent_user_id);
queries = mMissionsDb.orderByChild("status").equalTo("Available");
mMissionsDb.keepSynced(true);
mPendingList.setHasFixedSize(true);
mPendingList.setLayoutManager(new LinearLayoutManager(getContext()));
// Inflate the layout for this fragment
return mMainView;
}
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerAdapter<Mission, PendingFragment_User.MissionsViewHolder> firebaseMissionsUserRecyclerAdapter = new FirebaseRecyclerAdapter<Mission, PendingFragment_User.MissionsViewHolder>(
Mission.class,
R.layout.missions_single_layout,
PendingFragment_User.MissionsViewHolder.class,
queries
) {
#Override
protected void populateViewHolder(PendingFragment_User.MissionsViewHolder missionViewHolder, final Mission missionModel, int missionPosition) {
// Log.d(TAG, "inside populateViewHolder" + missionModel.getType() + " , " + missionModel.getDescription());
missionViewHolder.setMissionName(missionModel.getType());
missionViewHolder.setMissionDescription(missionModel.getDescription());
missionViewHolder.setMissionStatus(missionModel.getStatus());
missionViewHolder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Toast.makeText(view.getContext(), "esto es un boton"+ view.getNextFocusUpId(), Toast.LENGTH_SHORT).show();
Log.d(TAG,"The button was pressed");
}
});
}
};
mPendingList.setAdapter(firebaseMissionsUserRecyclerAdapter);
}
public static class MissionsViewHolder extends RecyclerView.ViewHolder {
View mView;
Button button ;
public MissionsViewHolder(View itemView) {
super(itemView);
mView = itemView;
button = (Button)mView.findViewById(R.id.pending_single_button);
}
public void setMissionName(String name){
TextView mMissionNameView = mView.findViewById(R.id.mission_single_name);
mMissionNameView.setText(name);
}
public void setMissionStatus(String status){
TextView mMissionStatusView = mView.findViewById(R.id.mission_single_status);
mMissionStatusView.setText(status);
if (status.equals("Available")){
mMissionStatusView.setTextColor(Color.parseColor("#008000"));;
} else {
mMissionStatusView.setTextColor(Color.parseColor("#FF0000"));;
}
}
public void setMissionDescription(String description){
TextView mMissionDescriptionView = mView.findViewById(R.id.mission_single_description);
mMissionDescriptionView.setText(description);
}
}
}
Try using a subclass rather than anonymous one. Then, you'll be able to access the getItem(int position) method of the adapter. Something along the lines of:
private class MissionAdapter extends FirebaseRecyclerAdapter<Mission, PendingFragment_User.MissionsViewHolder> {
public MissionAdapter(Query queries){
super(Mission.class, R.layout.missions_single_layout, PendingFragment_User.MissionsViewHolder.class, queries);
}
#Override
protected void populateViewHolder(PendingFragment_User.MissionsViewHolder missionViewHolder, final Mission missionModel, final int missionPosition) {
Log.d(TAG, "inside populateViewHolder" + missionModel.getType() + " , " + missionModel.getDescription());
missionViewHolder.setMissionName(missionModel.getType());
missionViewHolder.setMissionDescription(missionModel.getDescription());
missionViewHolder.setMissionStatus(missionModel.getStatus());
missionViewHolder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Mission clickedMission = MissionAdapter.this.getItem(missionPosition);
if (clickedMission != null){ // for the sake of being extra-safe
Log.d(TAG,"The button was pressed for mission: " + clickedMission.getType());
}
}
});
}
}
I made it print a log, but you should be able to do anything you want with the retrieved Mission object in there.

Passing data from list fragment to new activity

Am trying to pass data from list fragment in an activity to a new activity and getting null...
Here is my recyclerview adapter code...
package com.doctorapp.doctor;
import android.app.LauncherActivity;
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.AdapterView;
import android.widget.TextView;
import android.widget.Toast;
import android.util.Log;
import com.doctorapp.doctor.MyPatientsFragment.OnListFragmentInteractionListener;
import com.doctorapp.doctor.dummy.DummyContent.DummyItem;
import java.util.List;
/**
* {#link RecyclerView.Adapter} that can display a {#link DummyItem} and makes a call to the
* specified {#link OnListFragmentInteractionListener}.
* TODO: Replace the implementation with code for your data type.
*/
public class MypatientsRecyclerViewAdapter extends RecyclerView.Adapter<MypatientsRecyclerViewAdapter.ViewHolder> {
private final List<MyPatientsItem> mValues;
private final OnListFragmentInteractionListener mListener;
private Context context;
public MypatientsRecyclerViewAdapter(List<MyPatientsItem> items, OnListFragmentInteractionListener listener) {
mValues = items;
mListener = listener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fragment_patients, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.mypatientsItem = mValues.get(position);
holder.txtPatientName.setText(mValues.get(position).getPatient_name());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int patient_id = mValues.get(position).getPatient_id();
Toast.makeText(v.getContext(), "My Position : "+ patient_id, Toast.LENGTH_LONG).show();
Intent i = new Intent(context, PatientProfile.class);
i.putExtra("patient_id", patient_id);
context.startActivity(i);
if (null != mListener) {
//Toast.makeText(v.getContext(), "Am clicked.hey", Toast.LENGTH_LONG).show();
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onListFragmentInteraction(holder.mypatientsItem);
//Toast.makeText(v.getContext(), "Am clicked.", Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView txtPatientId;
public final TextView txtPatientName;
public MyPatientsItem mypatientsItem;
public ViewHolder(View view) {
super(view);
context = view.getContext();
mView = view;
txtPatientId = (TextView) view.findViewById(R.id.patient_id);
txtPatientName = (TextView) view.findViewById(R.id.patient_name);
}
#Override
public String toString() {
return super.toString() + " '" + txtPatientName.getText() + "'";
}
}
}
The list is populating fine and when I click it is also giving me toast with the right ID that needs to be passed so that the next activity can populate data for the right patient. In the second activity where I want to get data, it is giving null in all the ways I tried...
here is the code...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_patient_profile);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//String patient_id_str = (String) savedInstanceState.getSerializable("patient_id");
Intent intent = getIntent();
String patient_id_str = intent.getStringExtra("patient_id");
Toast.makeText(getApplicationContext(), "Load Patient : " + patient_id_str, Toast.LENGTH_LONG).show();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
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();
}
});
}
it always returns me null... am new to android and learning stuff with tutorials online so kind of hard for me to understand why it is not happening as many posts on the internet says this should work. please advise me on where am making mistake.
In intent extras, you are adding integer value, so you need to get the same in the target activity.
Check this out:
int patient_id_str = intent.getIntExtra("patient_id");
You are doing very perfect while sending data through Intent,
int patient_id = mValues.get(position).getPatient_id();
Intent i = new Intent(context, PatientProfile.class);
i.putExtra("patient_id", patient_id);
context.startActivity(i);
But while receiving data you have to get it through Bundle,
Bundle extras = getIntent().getExtras();
String patient_id_atr = (String) extras.get("patient_id");
dont Use Context Use getActivity;
And putExt Need setFlag

Categories

Resources