This is the edited version of my Fragment class inside my main activity. There were some bugs- it was not displaying anything and it was no longer saving the data to the database.
public static class DummyFragment extends Fragment {
int color;
public DummyFragment() {
}
#SuppressLint("ValidFragment")
public DummyFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
DatabaseReference mDatabaseGig;
final List<Dessert> dessertList;
// get the gig database
mDatabaseGig = FirebaseDatabase.getInstance().getReference("Gig Posts");
dessertList = new ArrayList<>();
mDatabaseGig.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// dessertList.clear();
for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
Dessert dessert = gigSnapshot.getValue(Dessert.class);
dessertList.add(dessert);
}
DessertAdapter adapter = new DessertAdapter(getContext());
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// possible to put progress dialogue
return view;
}
}
I already got the saving to firebase working perfectly and I'm using the MVC model - I created an adapter, a model and wired it to the main activity but my problem is how to use this model into the onAddValueEventChangedListener();
public class DessertAdapter extendsRecyclerView.Adapter<DessertAdapter.DessertVh> {
private List<Dessert> desserts = new ArrayList<>();
private static final int VIEW_TYPE_EMPTY_LIST_PLACEHOLDER = 0;
private static final int VIEW_TYPE_OBJECT_VIEW = 1;
private Context context;
// TODO: placeholder stuff here
#Override
public int getItemViewType(int position) {
if (desserts.isEmpty()) {
return VIEW_TYPE_EMPTY_LIST_PLACEHOLDER;
} else {
return VIEW_TYPE_OBJECT_VIEW;
}
}
public DessertAdapter(Context context) {
this.context = context;
this.desserts = desserts;
desserts = Dessert.prepareDesserts(
context.getResources().getStringArray(R.array.dessert_names),
context.getResources().getStringArray(R.array.dessert_descriptions),
context.getResources().getStringArray(R.array.dessert_amounts));
}
// TODO: another placeholder stuff here
#Override
public DessertVh onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.item_dessert, parent, false);
return new DessertAdapter.DessertVh(view);
}
#Override
public void onBindViewHolder(DessertVh holder, int position) {
Dessert dessert = desserts.get(position);
holder.mName.setText(dessert.getName());
holder.mDescription.setText(dessert.getDescription());
holder.mFirstLetter.setText(String.valueOf(dessert.getFirstLetter()));
holder.mPrice.setText(String.valueOf(dessert.getAmount()));
}
#Override
public int getItemCount() {
// if nothing, return null,
// else return the number of items in the list
return desserts == null ? 0 : desserts.size();
}
public static class DessertVh extends RecyclerView.ViewHolder {
private TextView mName;
private TextView mPrice;
private TextView mDescription;
private TextView mFirstLetter;
public DessertVh(View itemView) {
super(itemView);
mName = (TextView) itemView.findViewById(R.id.txt_name);
mPrice = (TextView) itemView.findViewById(R.id.txt_price);
mDescription = (TextView) itemView.findViewById(R.id.txt_desc);
mFirstLetter = (TextView) itemView.findViewById(R.id.txt_firstletter);
}
}
}
main activity where the tabs are displayed
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs_header);
// get the gig database
mDatabaseGig = FirebaseDatabase.getInstance().getReference("Gig Posts");
dessertList = new ArrayList<>();
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this , this )
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
This handles the display of the data
#Override
public void onStart(){
super.onStart();
mFirebaseAuth.addAuthStateListener(firebaseAuthListener);
// load the data from database here
mDatabaseGig.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dessertList.clear();
for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
Dessert dessert = gigSnapshot.getValue(Dessert.class);
dessertList.add(dessert);
}
// maybe this will work?
DummyFragment dummyFragment = new DummyFragment();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
some code missing here but still part of mainactivity
This is the Dummy Fragment Class inside the main activity
public static class DummyFragment extends Fragment {
int color;
public DummyFragment() {
}
#SuppressLint("ValidFragment")
public DummyFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
// possible to put progress dialogue
DessertAdapter adapter = new DessertAdapter(getContext());
recyclerView.setAdapter(adapter);
return view;
}
}
Put the Firebase code inside the Fragment, not the Activity and also pass the dessertList as a param to the DessertAdapter.
Example:
public static class DummyFragment extends Fragment {
int color;
public DummyFragment() {
}
#SuppressLint("ValidFragment")
public DummyFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
DatabaseReference mDatabaseGig;
final List<Dessert> dessertList;
// get the gig database
mDatabaseGig = FirebaseDatabase.getInstance().getReference("Gig Posts");
dessertList = new ArrayList<>();
DessertAdapter adapter = new DessertAdapter(getContext(), dessertList);
recyclerView.setAdapter(adapter);
mDatabaseGig.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// dessertList.clear();
for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
Dessert dessert = gigSnapshot.getValue(Dessert.class);
dessertList.add(dessert);
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// possible to put progress dialogue
return view;
}
}
Related
I did the code below, used the adapter to show the list, and a button to add a comment to list item, it shows the logcat "ViewPostIme pointer 0 and ViewPostIme pointer 1", upon clicking the comment button.
Upon compilation it doesn't show any error, I tried to use many references via google but nothing works out.
My basic idea is to call the comment button with an associated list item to perform the comment activity.
Adapter class
public class PostsAdapter extends FirestoreRecyclerAdapter<PostsModel, PostsAdapter.PostsHolder> {
private OnItemClickListener listener;
private View.OnClickListener buttonListener;
private String id;
private static final String TAG = "DocSnippets";
public PostsAdapter(#NonNull FirestoreRecyclerOptions<PostsModel> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull PostsHolder holder, int position, #NonNull PostsModel model) {
//retrieve the fields here
holder.textViewDescription.setText(model.getPostContent());
holder.textViewPriority.setText(String.valueOf(model.getSpinnerC()));
holder.textViewPriority.setText(String.valueOf(model.getTimestamp()));
}
#NonNull
#Override
public PostsHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_list_layout,
parent, false);
return new PostsHolder(v);
}
public void deleteItem(int position) {
getSnapshots().getSnapshot(position).getReference().delete();
}
public void setOnClickListener(OnClickListener postKey) {
}
class PostsHolder extends RecyclerView.ViewHolder {
//first declare here the elements to be displayed in the cardview.
TextView textViewTitle;
TextView textViewDescription;
TextView textViewPriority;
Button commentsbutton;
public PostsHolder(final View itemView) {
super(itemView);
textViewTitle = itemView.findViewById(R.id.post_etPostTitle);
textViewDescription = itemView.findViewById(R.id.post_description);
textViewPriority = itemView.findViewById(R.id.post_time);
commentsbutton = itemView.findViewById(R.id.commenting_button);
commentsbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION && buttonListener != null) {
buttonListener.onClick(itemView);
}
}
});
}
}
public interface OnClickListener
{
void OnClickListener(DocumentSnapshot documentSnapshot, int position);
}
public void setOnClickListener(View.OnClickListener onClickListener) {
this.buttonListener = onClickListener;
}
public interface OnItemClickListener {
void onItemClick(DocumentSnapshot documentSnapshot, int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
}
Fragment Class
public class HomeFragment extends Fragment {
RelativeLayout mParent;
//FloatingActionButton addButton;
private static final String TAG = "DocSnippets";
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference PostsRef = db.collection("posts");
private PostsAdapter adapter;
private FirestoreRecyclerOptions options;
private FirebaseAuth mAuth;
private String mUserId, id;
private Button commentsbutton;
RecyclerView recyclerView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
//just change the fragment_dashboard
//with the fragment you want to inflate
//like if the class is HomeFragment it should have R.layout.home_fragment
//if it is DashboardFragment it should have R.layout.fragment_dashboard
View view = inflater.inflate(R.layout.fragment_home, container, false);
final FragmentActivity c = getActivity();
LinearLayoutManager layoutManager = new LinearLayoutManager(c);
Query query = PostsRef.orderBy("timestamp", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<PostsModel> options = new FirestoreRecyclerOptions.Builder<PostsModel>()
.setQuery(query, PostsModel.class)
.build();
adapter = new PostsAdapter(options);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(c));
recyclerView.setAdapter(adapter);
commentsbutton = (Button) view.findViewById(R.id.commenting_button);
mParent =view.findViewById(R.id.relative_home);
mAuth = FirebaseAuth.getInstance();
mUserId = mAuth.getUid();
adapter.setOnItemClickListener(new PostsAdapter.OnItemClickListener() {
#Override
public void onItemClick(DocumentSnapshot documentSnapshot, int position) {
PostsModel note = documentSnapshot.toObject(PostsModel.class);
id = documentSnapshot.getId();
String path = documentSnapshot.getReference().getPath();
Log.d(TAG, "String post Id is: " + id);
}
});
adapter.setOnClickListener(new PostsAdapter.OnClickListener() {
#Override
public void OnClickListener(DocumentSnapshot documentSnapshot, int position) {
PostsModel note = documentSnapshot.toObject(PostsModel.class);
id = documentSnapshot.getId();
String path = documentSnapshot.getReference().getPath();
Log.d(TAG, "String post Id is: " + id);
Intent toCommentActivity = new Intent(getContext(), CommentActivity.class);
toCommentActivity.putExtra("PostKey", id);
getContext().startActivity(toCommentActivity);
}
});
return view;
}
private String getTime(long timestamp){
long ts = timestamp*1000;
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm a");
String time = sdf.format(new Date(ts));
return time;
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
}
I am not able to bind recyclerview with adapter using BottomSheetDialog
Here is my MainActivity
public class MainActivity extends AppCompatActivity {
BottomAppBar bottomAppBar;
FloatingActionButton floatingActionButton;
ImageView emptyView;
private RecyclerView recyclerView;
private List<AppModel> appModelResult = new ArrayList<>();
private AppAdapter appAdapter;
private RecyclerView.LayoutManager layoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
emptyView = findViewById(R.id.empty_view);
bottomAppBar = findViewById(R.id.bottom_app_bar);
setSupportActionBar(bottomAppBar);
floatingActionButton =findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AddAppDialog addAppDialog = new AddAppDialog();
addAppDialog.show(getSupportFragmentManager(),"AddBottomSheet");
}
});
bottomAppBar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
BottomSheetDialog bottomSheet = new BottomSheetDialog();
bottomSheet.show(getSupportFragmentManager(), "BottomSheet");
}
});
//RecyclerView Binding
recyclerView = findViewById(R.id.app_list);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
appAdapter = new AppAdapter(appModelResult);
recyclerView.setAdapter(appAdapter);
appAdapter.setItems(appModelResult);
if(appAdapter.getItemCount() == 0){
recyclerView.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
}else{
recyclerView.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
}
}}
And here is my BottomSheetDialog, where i input 2 EditText and a Spinner.Taping on Save Button should display written data on the main screen, however there is nothing on a display.
public class AddAppDialog extends BottomSheetDialog implements AdapterView.OnItemSelectedListener {
static TextInputEditText appUrl;
TextInputEditText appDesc;
MaterialButton saveButton;
Spinner spinnerCategory;
AppModel appModel = new AppModel();
List<AppModel> appModelResult = new ArrayList<>();
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_bottomsheet_add,container,false);
appUrl = v.findViewById(R.id.app_url);
appDesc = v.findViewById(R.id.app_desc);
saveButton = v.findViewById(R.id.save_button);
spinnerCategory = v.findViewById(R.id.spinner_category);
List<String> categories = new ArrayList<String>();
categories.add(0,"Choose category");
categories.add("Education");
categories.add("Entertainment");
categories.add("Games");
categories.add("Health");
categories.add("Personalization");
categories.add("Social");
categories.add("Tools");
ArrayAdapter<CharSequence> adapter = new ArrayAdapter(getActivity().getApplicationContext(),android.R.layout.simple_spinner_item,categories);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerCategory.setAdapter(adapter);
spinnerCategory.setOnItemSelectedListener(this);
appUrl.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) { }
#Override
public void afterTextChanged(Editable s) {
new Parse().execute();
}
});
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(appUrl.getText().toString().trim().length() != 0) {
appModel.setAppDesc(appDesc.getText().toString());
appModelResult.add(0,new AppModel(Parse.eImage,Parse.eName,appModel.getAppCategory(),appModel.getAppDesc()));
System.out.println(appModelResult.get(0).getImage());
System.out.println(appModelResult.get(0).getAppText());
System.out.println(appModelResult.get(0).getAppCategory());
System.out.println(appModelResult.get(0).getAppDesc());
dismiss();
}else{
appUrl.setError("URL is required :)");
}
}
});
return v;
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(parent.getItemAtPosition(position).equals("Choose category")){
}else{
String selectedCategory = parent.getItemAtPosition(position).toString();
appModel.setAppCategory(selectedCategory);
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}}
Finally, my Adapter for RecyclerView looks like that:
public class AppAdapter extends RecyclerView.Adapter<AppAdapter.AppViewHolder> {
private List<AppModel> mAppModelList;
public AppAdapter(List<AppModel> appModelList) {
mAppModelList = appModelList;
}
public static class AppViewHolder extends RecyclerView.ViewHolder{
public ImageView appImage;
public TextView appText,appCategory,appDesc;
public AppViewHolder(#NonNull View itemView) {
super(itemView);
appImage = itemView.findViewById(R.id.app_image_list);
appText = itemView.findViewById(R.id.app_text_list);
appCategory = itemView.findViewById(R.id.app_category_list);
appDesc = itemView.findViewById(R.id.app_desc_list);
}
}
public void setItems(List<AppModel> items){
mAppModelList.addAll(items);
notifyDataSetChanged();
}
public void clearItems(){
mAppModelList.clear();
notifyDataSetChanged();
}
#NonNull
#Override
public AppViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_list,parent,false);
AppViewHolder appViewHolder = new AppViewHolder(v);
return appViewHolder;
}
#Override
public void onBindViewHolder(#NonNull AppViewHolder holder, int position) {
AppModel appModel = mAppModelList.get(position);
holder.appText.setText(appModel.getAppText());
holder.appCategory.setText(appModel.getAppCategory());
holder.appDesc.setText(appModel.getAppDesc());
Picasso.get().load(appModel.getImage()).into(holder.appImage);
}
#Override
public int getItemCount() {
return mAppModelList.size();
}}
I think that XML files are OK,therefore i have not pasted it here, and the only problem is regarding to binding process.
Solved it adding RecyclerView in Fragment and refreshing list via detach & attach
getActivity().getSupportFragmentManager().beginTransaction().detach(getFragmentManager().findFragmentById(R.id.recycler_fragment)).commitNowAllowingStateLoss();
getActivity().getSupportFragmentManager().beginTransaction().attach(new RecyclerFragment()).commitAllowingStateLoss();
Attention!
In order reload fragment use only dynamic fragments.
I get this error and I dont know how to fix it
java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.get(ArrayList.java:411)
at com.tijdelijk.firebasetest.Start$1.populateViewHolder(Start.java:69)
at com.tijdelijk.firebasetest.Start$1.populateViewHolder(Start.java:64)
I am working with firebase database and based on CategoryId I put the items in a arraylist for the SubCategories my code:
public class CategoryFragment extends Fragment {
View myFragment;
RecyclerView listCategory;
RecyclerView.LayoutManager layoutManager;
FirebaseRecyclerAdapter<Category, CategoryViewHolder> adapter;
FirebaseDatabase database;
DatabaseReference categories;
DatabaseReference subCategory;
public static CategoryFragment newInstance() {
CategoryFragment fragment = new CategoryFragment();
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = FirebaseDatabase.getInstance();
categories = database.getReference("Category");
subCategory = database.getReference("SubCategory");
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
myFragment = inflater.inflate(R.layout.fragment_category, container, false);
listCategory = (RecyclerView) myFragment.findViewById(R.id.listCategory);
listCategory.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(container.getContext());
listCategory.setLayoutManager(layoutManager);
loadCategories();
return myFragment;
}
private void loadCategories() {
adapter = new FirebaseRecyclerAdapter<Category, CategoryViewHolder>(
Category.class,
R.layout.category_layout,
CategoryViewHolder.class,
categories
) {
#Override
protected void populateViewHolder(CategoryViewHolder viewHolder, final Category model, int position) {
viewHolder.category_name.setText(model.getName());
Picasso.with(getActivity())
.load(model.getImage())
.into(viewHolder.category_image);
viewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Intent startGame = new Intent(getActivity(), Start.class);
Common.categoryId = adapter.getRef(position).getKey();
loadSubCategory(Common.categoryId);
startActivity(startGame);
}
});
}
};
adapter.notifyDataSetChanged();
listCategory.setAdapter(adapter);
}
private void loadSubCategory(String categoryId) {
//Clear list if there are old subCategory
if (Common.subCategoryList.size() > 0) {
Common.subCategoryList.clear();
}
subCategory.orderByChild("CategoryId").equalTo(categoryId)
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
SubCategory ques = postSnapshot.getValue(SubCategory.class);
Common.subCategoryList.add(ques);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
in this activity I want to display also a recyclerview but this time based on the arraylist I got from the categoryfragment here is my code:
public class Start extends AppCompatActivity {
FirebaseDatabase database;
DatabaseReference subCategory;
FirebaseRecyclerAdapter<SubCategory, SubCategoryViewHolder> adapter;
RecyclerView listSubCategory;
RecyclerView.LayoutManager layoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
database = FirebaseDatabase.getInstance();
subCategory = database.getReference("SubCategory");
listSubCategory = findViewById(R.id.listSubCategory);
listSubCategory.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getBaseContext());
listSubCategory.setLayoutManager(layoutManager);
loadSubCategories();
adapter.notifyDataSetChanged();
listSubCategory.setAdapter(adapter);
}
private void loadSubCategories() {
adapter = new FirebaseRecyclerAdapter<SubCategory, SubCategoryViewHolder>(
SubCategory.class,
R.layout.subcategory_layout,
SubCategoryViewHolder.class,
subCategory
) {
#Override
protected void populateViewHolder(SubCategoryViewHolder viewHolder, SubCategory model, int position) {
viewHolder.subcategory_nlname.setText(Common.subCategoryList.get(position).getLatijnseNaam());
viewHolder.subcategory_ltname.setText(Common.subCategoryList.get(position).getNederlandseNaam());
viewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Intent startGame = new Intent(Start.this, Start.class);
Common.categoryId = adapter.getRef(position).getKey();
startActivity(startGame);
}
});
}
};
}
}
here is my viewholder:
public class SubCategoryViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener{
public TextView subcategory_nlname;
public TextView subcategory_ltname;
private ItemClickListener itemClickListener;
public SubCategoryViewHolder(View itemView) {
super(itemView);
subcategory_ltname = itemView.findViewById(R.id.latijnse_naam);
subcategory_nlname = itemView.findViewById(R.id.nederlandse_naam);
// itemView.findViewById(R.id.btnPlay).setOnClickListener(this);
}
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
#Override
public void onClick(View view) {
itemClickListener.onClick(view,getAdapterPosition(),false);
}
}
IndexOutOfBoundException means that you are trying to access a value that is at an index out of the array.
In your case, you have an array of two values. So you have the keys 0 and 1. As said in the error, your code is trying to access the index 2, which does not exist.
You have to check that you are accessing an index that is in the range of values of the array.
Good day to you.
Recycle view not displaying data its shows an empty screen, It displays data when I go back and click the icon again. Not sure why I'm facing this problem.Please check the activity, adaptor and fragment code below. I'm new to android and I'm doing my capstone project it would be great if you can help me.
public class AppDetailsActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("App Details");
setContentView(R.layout.activity_app);
AppDetailsFragment newFragment = new AppDetailsFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.recordAppFragmentContainer, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
public void refreshAppDuration(View v) {
Intent intent = new Intent(this, AppDetailsActivity.class);
startActivity(intent);
}
protected void onPause() {
super.onPause();
}
protected void onStop() {
super.onStop();
}
protected void onDestroy() {
super.onDestroy();
}
public void onBackAppDuration(View v) {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
Adaptor
public class AppDetailsAdaptor extends RecyclerView.Adapter<AppDetailsAdaptor.ViewHolder> {
private List<AppUsage> mApps;
private Context mContext;
public AppDetailsAdaptor(Context context, List<AppUsage> apps) {
mApps = apps;
mContext = context;
}
private Context getContext() {
return mContext;
}
#Override
public AppDetailsAdaptor.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View appUsageView = inflater.inflate(R.layout.item_app_details, parent, false);
// Return a new holder instance
AppDetailsAdaptor.ViewHolder viewHolder = new AppDetailsAdaptor.ViewHolder(appUsageView);
return viewHolder;
}
#Override
public void onBindViewHolder(AppDetailsAdaptor.ViewHolder viewHolder, final int position) {
// Get the data model based on position
final AppUsage ch = mApps.get(position);
// Set item views based on your views and data model
viewHolder._appTextView.setText(ch.getAppName());
viewHolder._durationTextView.setText(ch.getDurationInMinutes());
viewHolder._dateTextView.setText(ch.getDate().substring(0,10));
final String key = ch.getKey();
}
#Override
public int getItemCount() {
return mApps.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView _appTextView;
public TextView _durationTextView;
public TextView _dateTextView;
super(itemView);
_appTextView = (TextView) itemView.findViewById(R.id.rvs_app_name);
_durationTextView = (TextView) itemView.findViewById(R.id.rvs_app_duration);
_dateTextView =(TextView) itemView.findViewById(R.id.rvs_app_date);
}
}
}
Fragment
public class AppDetailsFragment extends Fragment {
final FirebaseDatabase database = FirebaseDatabase.getInstance();
ArrayList<AppUsage> appList = new ArrayList<>();
ArrayList<AppUsage> appListTemp = new ArrayList<>();
ArrayList<AppUsage> appListAdaptor = new ArrayList<>();
ArrayList<AppUsage> appObject = new ArrayList<>();
ArrayList<AppUsage> appListDate = new ArrayList<>();
private AppDetailsFragment.OnFragmentInteractionListener mListener;
private RecyclerView rvApp;
private RecyclerView.Adapter appAdaptor;
private RecyclerView.LayoutManager eLayoutManager;
private EditText date;
private static final int DIALOG_DATE_PICKER = 100;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_app_list, container, false);
rvApp = (RecyclerView) rootView.findViewById(R.id.rvAppList);
rvApp.setHasFixedSize(true);
eLayoutManager = new LinearLayoutManager(getActivity());
rvApp.setLayoutManager(eLayoutManager);
appList = getAllAppRecords();
appAdaptor = new AppDetailsAdaptor(getActivity(), appList);
rvApp.setAdapter(appAdaptor);
return rootView;
}
public ArrayList<AppUsage> getAllAppRecords(){
DatabaseReference ref = database.getReference();
ref.child("AppUsage").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
appObject.clear();
HashMap<String,Object> app = null;
Iterator<DataSnapshot> items = dataSnapshot.getChildren().iterator();
while(items.hasNext()){
DataSnapshot item = items.next();
Log.e("Listener",item.toString() );
app =(HashMap<String, Object>) item.getValue();
appObject.add(new AppUsage(app.get("appName").toString(),app.get("durationInMinutes").toString(),app.get("date").toString(),item.getKey()));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return appObject;
}
When I start activity with fragment, recyclerview and adapter the app is stopping. I don't know where the problem is. I've tried different methods.
My logcat:
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.support.v7.widget.RecyclerView.setAdapter(android.support.v7.widget.RecyclerView$Adapter)'
on a null object reference
at com.orthodox.FeedActivity.onStart(FeedActivity.java:133)
at android.support.v4.app.Fragment.performStart(Fragment.java:2287)
My code:
public class FeedActivity extends Fragment{
private RecyclerView mBlogList;
private Query mQuery;
private Query mQueryck;
private DatabaseReference mDatabaseUsers;
private FirebaseUser mCurrent;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
FirebaseRecyclerAdapter mAdapter;
public FeedActivity() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FragmentActivity c = getActivity();
View layout = inflater.inflate(R.layout.fragment_feed, container, false);
return layout;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
mBlogList = (RecyclerView) view.findViewById(R.id.blog_list);
mBlogList.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
mBlogList.setLayoutManager(layoutManager);
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if(firebaseAuth.getCurrentUser() == null){
Intent loginIntent = new Intent(getActivity(), SignUpActivity.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(loginIntent);
}
}
};
mQuery = FirebaseDatabase.getInstance().getReference().child("Blog").limitToLast(20);
mQuery.keepSynced(true);
mQueryck = FirebaseDatabase.getInstance().getReference().child("Block").limitToLast(20);
mQueryck.keepSynced(true);
mDatabaseUsers = FirebaseDatabase.getInstance().getReference().child("users");
mDatabaseUsers.keepSynced(true);
mCurrent = mAuth.getCurrentUser();
}
#Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
FirebaseRecyclerOptions<User> options = new FirebaseRecyclerOptions.Builder<User>().setQuery(mQuery, User.class).build();
FirebaseRecyclerOptions<User> optionss = new FirebaseRecyclerOptions.Builder<User>().setQuery(mQueryck, User.class).build();
mAdapter = new FirebaseRecyclerAdapter<User, BlogViewHolder>(options) {
#Override
public BlogViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Create a new instance of the ViewHolder
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.blog_row, parent, false);
return new BlogViewHolder(view);
}
#Override
protected void onBindViewHolder(BlogViewHolder viewHolder, int position, User model) {
final String post_key = getRef(position).getKey();
viewHolder.setTitle(model.getTitle());
viewHolder.setDesc(model.getDesc());
viewHolder.setTime(model.getFirstname());
viewHolder.setImage(getApplicationContext(), model.getImage());
}
};
mBlogList.setAdapter(mAdapter);
mAdapter.startListening();
mAdapter = new FirebaseRecyclerAdapter<User, BlogViewHolder>(optionss) {
#Override
protected void onBindViewHolder(BlogViewHolder viewHolder, int position, User model) {
final String post_key = getRef(position).getKey();
viewHolder.setTitle(model.getTitle());
viewHolder.setDesc(model.getDesc());
viewHolder.setTime(model.getFirstname());
viewHolder.setImage(getApplicationContext(), model.getImage());
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent bsingle = new Intent(getActivity(), SinglePostActivity.class);
bsingle.putExtra("post", post_key);
startActivity(bsingle);
}
});
}
#Override
public BlogViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.blog_row, parent, false);
return new BlogViewHolder(view);
}
};
}
public static class BlogViewHolder extends RecyclerView.ViewHolder {
View mView;
public BlogViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setTitle(String title){
TextView post_title = (TextView) mView.findViewById(R.id.post_title);
post_title.setText(title);
}
public void setDesc(String desc){
TextView post_desc = (TextView) mView.findViewById(R.id.post_desc);
post_desc.setText(desc);
}
public void setImage(Context ctx, String image){
if (image != null) {
ImageView post_image = (ImageView) mView.findViewById(R.id.post_image);
Picasso.with(ctx).load(image).into(post_image);
}
else {
ImageView post_image = (ImageView) mView.findViewById(R.id.post_image);
post_image.setVisibility(View.GONE);
}
}
public void setTime(String time){
TextView post_time = (TextView) mView.findViewById(R.id.post_username);
post_time.setText(time);
}
Initialize your all views in onCreateView method.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FragmentActivity c = getActivity();
View layout = inflater.inflate(R.layout.fragment_feed, container, false);
mBlogList = (RecyclerView) layout.findViewById(R.id.blog_list);
return layout;
}