I'm working on an Android project and I want to make a swipeable activity that has a textview in it so When the user swipes the textview value changes!
I want to make the SingleItem class swipeable so that the user can see more content about the book when they swipe.
Here is my code!!!
MainActivity.java
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
List<Book> books;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
books = new ArrayList<>();
books.add(new Book("Rich Dad Poor Dad", "Rich Dad Poor Dad is a 1997 book written by Robert Kiyosaki and Sharon Lechter.", "Robert Kiyosaki"));
books.add(new Book("Awaken The Giant Within", "Wake up and take control of your life! From the bestselling author of Inner Strength, Unlimited Power, and MONEY Master the Game", "Anthony Robbins"));
mRecyclerView = findViewById(R.id.my_recyclerview);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mAdapter = new RecyclerViewAdapter(books, this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
}
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private List<Book> bookList;
private Context mContext;
public RecyclerViewAdapter(List<Book> bookList, Context mContext) {
this.bookList = bookList;
this.mContext = mContext;
}
#NonNull
#Override
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view ;
LayoutInflater mInflater = LayoutInflater.from(mContext);
view = mInflater.inflate(R.layout.item_list,viewGroup,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerViewAdapter.ViewHolder viewHolder, final int i) {
viewHolder.bookTitle.setText(bookList.get(i).getmTitle());
viewHolder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext, SingleItem.class);
intent.putExtra("Description", bookList.get(i).getmDescription());
intent.putExtra("Author", bookList.get(i).getmAuthor());
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return bookList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public View view;
public TextView bookTitle;
public CardView cardView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
bookTitle = itemView.findViewById(R.id.book_title);
cardView = itemView.findViewById(R.id.my_card_view);
view = itemView;
}
}
SingleItem.java
public class SingleItem extends AppCompatActivity {
private TextView bookDescription, bookAuthor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_item);
bookDescription = findViewById(R.id.book_description);
bookAuthor = findViewById(R.id.book_author);
// Recieve data
Intent intent = getIntent();
String Desc = intent.getExtras().getString("Description");
String Author = intent.getExtras().getString("Author");
bookDescription.setText(Desc);
bookAuthor.setText(Author);
}
Book.java
public class Book {
private String mTitle;
private String mDescription;
private String mAuthor;
public Book(){
}
public Book(String mTitle, String mDescription, String mAuthor) {
this.mTitle = mTitle;
this.mDescription = mDescription;
this.mAuthor = mAuthor;
}
public String getmTitle() {
return mTitle;
}
public void setmTitle(String mTitle) {
this.mTitle = mTitle;
}
public String getmDescription() {
return mDescription;
}
public void setmDescription(String mDescription) {
this.mDescription = mDescription;
}
public String getmAuthor() {
return mAuthor;
}
public void setmAuthor(String mAuthor) {
this.mAuthor = mAuthor;
}
}
I want to make the SingleItem class swipeable so that the user can see more content about the book when they swipe.
Use SwipeRefreshLayout in your activity to Swipe down and update textview
<android.support.v7.widget.SwipeRefreshLayout
android:id="#+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.SwipeRefreshLayout>
Then in your Activity.java
TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
mTextView=findViewById(R.id.textView);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SwipeRefreshLayout pullToRefresh = findViewById(R.id.pullToRefresh);
pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mTextView.setText("My new text") // update here
pullToRefresh.setRefreshing(false);
}
});
}
Maybe you'd like to use an SeekBar? It has to be swiped and TextView has to be showing text, not vice versa. Set your SeekBar and TextView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="#dimen/small_padding">
<TextView
android:id="#+id/text_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<SeekBar
android:id="#+id/seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"/>
</LinearLayout>
Then, MainActivity.java:
public class MainActivity extends AppCompatActivity {
TextView textView;
SeekBar seekBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text_progress);
seekBar = findViewById(R.id.seek_bar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
textView.setText("Your progress is " + progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
Related
Here, I want to Retrieve the image and text into a RecyclerView which is the ImageActivity: here is its XML File
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ImagesActivity">
<ProgressBar
android:id="#+id/progress_circle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
The ImagesActivity Java class: Here I want to set the data into the RecyclerView using OnBindViewHolder from ImageAdapter Activity.
public class ImagesActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private ImageAdapter mAdapter;
private DatabaseReference mDatabaseRef;
private ProgressBar mProgressCircle;
private List<Upload> mUploads;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_images);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mProgressCircle = findViewById(R.id.progress_circle);
mUploads = new ArrayList<>();
mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");
mDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Upload upload = postSnapshot.getValue(Upload.class);
mUploads.add(upload);
}
mAdapter = new ImageAdapter(ImagesActivity.this, mUploads);
mRecyclerView.setAdapter(mAdapter);
mProgressCircle.setVisibility(View.INVISIBLE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(ImagesActivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
mProgressCircle.setVisibility(View.INVISIBLE);
}
});
}
}
ImageAdapterActiviy Java Class which retrive the data from firebase using OnBindeViewHolder:
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
private Context mContext;
private List<Upload> mUploads;
public ImageAdapter(Context context, List<Upload> uploads) {
mContext = context;
mUploads = uploads;
}
#Override
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.image_item, parent, false);
return new ImageViewHolder(v);
}
#Override
public void onBindViewHolder(ImageViewHolder holder, int position) {
Upload uploadCurrent = mUploads.get(position);
holder.textViewName.setText(uploadCurrent.getName());
Picasso.get()
.load(uploadCurrent.getImageUrl())
.fit()
.centerCrop()
.into(holder.imageView);
}
#Override
public int getItemCount() {
return mUploads.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
public TextView textViewName;
public ImageView imageView;
public ImageViewHolder(View itemView) {
super(itemView);
textViewName = itemView.findViewById(R.id.text_view_name);
imageView = itemView.findViewById(R.id.image_view_upload);
}
}
}
Upload Java Class: here the setter and getter method.
public class Upload {
private String mName;
private String mImageUrl;
public Upload() {
//empty constructor needed
}
public Upload(String name, String imageUrl) {
if (name.trim().equals("")) {
name = "No Name";
}
mName = name;
mImageUrl = imageUrl;
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public String getImageUrl() {
return mImageUrl;
}
public void setImageUrl(String imageUrl) {
mImageUrl = imageUrl;
}
}
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 am trying to implement OnClick in my recyclerview,but i failed miserably with all the searches how to solve this problem.
I want by clicking on my cardview to go to another activity/even better fragment with another expandable lists,but i can't even do this for now.
Any help is highly appreciated
MainActivity code
package com.oleg.firestoretest;
public static final String TAG = "FireLog";
private CollectionReference noteBookRef;
private FirebaseFirestore mFirestore;
private NoteAdapter adapter;
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFirestore = FirebaseFirestore.getInstance();
noteBookRef = mFirestore.collection("Notebook");
setupRecyclerView();
}
private void setupRecyclerView() {
Query query = noteBookRef.orderBy("priority", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<Note> options = new FirestoreRecyclerOptions.Builder<Note>()
.setQuery(query,Note.class)
.build();
adapter = new NoteAdapter(options);
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
public Note() {
}
public Note(String title, String content, int priority) {
this.title = title;
this.content = content;
this.priority = priority;
}
public String getTitle() {
return title;
}
public String getContent() {
return content;
}
public int getPriority() {
return priority;
}
}
public class NoteAdapter extends FirestoreRecyclerAdapter<Note, NoteAdapter.NoteHolder> {
private Context mContext;
public NoteAdapter(#NonNull FirestoreRecyclerOptions<Note> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull NoteHolder noteHolder, int i, #NonNull Note note) {
noteHolder.title.setText(note.getTitle());
noteHolder.content.setText(note.getContent());
noteHolder.priority.setText(String.valueOf(note.getPriority()));
}
#NonNull
#Override
public NoteHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.note_item,
parent, false);
return new NoteHolder(v);
}
class NoteHolder extends RecyclerView.ViewHolder {
TextView title;
TextView content;
TextView priority;
public NoteHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title_text);
content = itemView.findViewById(R.id.content_text);
priority = itemView.findViewById(R.id.priority_text);
}
}
}
Here the Code u need:
class NoteHolder extends RecyclerView.ViewHolder {
TextView title;
TextView content;
TextView priority;
CardView cardView;
public NoteHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title_text);
content = itemView.findViewById(R.id.content_text);
priority = itemView.findViewById(R.id.priority_text);
cardView = itemView.findViewById(R.id.cardView);
}
private void bind(){
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(FirstActivity.this, SecoundActivity.class);
startActivity(intent);
}
});
}
}
Fixed it with this code!!!
public NoteHolder(#NonNull final View itemView) {
super(itemView);
cardView = itemView.findViewById(R.id.cardview);
title = itemView.findViewById(R.id.title_text);
content = itemView.findViewById(R.id.content_text);
priority = itemView.findViewById(R.id.priority_text);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
itemView.getContext().startActivity(new Intent(itemView.getContext(),Empty.class));
}
});
}
I am stuck with this error for a long time now, I am new to JAVA.
I want to click an item on the RecyclerView (currently on a fragment) that got populated from Firebase. Once I click on it, it should take me to the next fragment by parcing some data and also the position of the item.
Here is my adapter, CustomAdapter.java
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
public CustomAdapter(ArrayList<Userpost> data) {
this.data = data;
}
public interface OnItemClickListener{
void onItemClick(Userpost userpost, int activityNumber);
}
private ArrayList<Userpost> data;
private static final int ACTIVITY_NUM = 4;
private OnItemClickListener listener;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView textViewName;
TextView textViewVersion;
SquareImageView imageView;
private final Context context;
public View mCardView;
public MyViewHolder(View itemView) {
super(itemView);
context = itemView.getContext();
this.textViewName = (TextView) itemView.findViewById(R.id.textViewName);
this.textViewVersion = (TextView) itemView.findViewById(R.id.textViewVersion);
this.imageView = (SquareImageView) itemView.findViewById(R.id.imageView);
this.mCardView = itemView.findViewById(R.id.card_view);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(context, "Position is " +getAdapterPosition(),Toast.LENGTH_SHORT).show();
}
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
Log.d(TAG, "MyViewHolder: setting up adapter for profile fragment");
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards_layout, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(itemView);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int Position) {
Log.d(TAG, "onBindViewHolder: setting up adapter for profile fragment");
TextView textViewName = holder.textViewName;
TextView textViewVersion = holder.textViewVersion;
final ImageView imageView = holder.imageView;
textViewName.setText(data.get(Position).getPheading());
textViewVersion.setText(data.get(Position).getDescriptionpost());
Picasso.with(holder.imageView.getContext()).load(data.get(Position).getImage_path()).into(holder.imageView);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "Recycle Click" + Position, Toast.LENGTH_SHORT).show();
listener.onItemClick(data.get(Position), ACTIVITY_NUM);
}
});
}
#Override
public int getItemCount() {
return data.size();
}
}
Here's fragment, ProfileFragment.java
public class ProfileFragment extends Fragment {
private static final String TAG = "ProfileFragment";
private static final int ACTIVITY_NUM = 4;
//firebase stuff
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference myRef;
private FirebaseMethods mFirebaseMethods;
// Recycler View Widgets
private static RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private static RecyclerView recyclerView;
private static ArrayList<Userpost> data;
private static ArrayList<Integer> removedItems;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_profile, container, false);
gridView = (GridView) view.findViewById(R.id.gridView);
recyclerView = (RecyclerView) view.findViewById(R.id.my_recycler_view);
cardView = (CardView) view.findViewById(R.id.card_view);
toolbar = (Toolbar) view.findViewById(R.id.profileToolBar);
bottomNavigationView = (BottomNavigationViewEx) view.findViewById(R.id.bottomNavViewBar);
mContext = getActivity();
mFirebaseMethods = new FirebaseMethods(getActivity());
//Recycler View class
super.onCreate(savedInstanceState);
data = new ArrayList<Userpost>();
recyclerView = (RecyclerView) view.findViewById(R.id.my_recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new CustomAdapter(data);
recyclerView.setAdapter(adapter);
updateArrayList();
private void updateArrayList() {
Log.d(TAG, "updateArrayList: setting up for profile fragment");
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference
.child(getString(R.string.dbname_user_posts))
.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.d(TAG, "onChildAdded: explore fragment");
data.add(dataSnapshot.getValue(Userpost.class));
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
Userpost model = dataSnapshot.getValue(Userpost.class);
final int index = getItemIndex(model);
data.set(index, model);
adapter.notifyItemChanged(index);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private int getItemIndex(Userpost user) {
Log.d(TAG, "getItemIndex: setting up for profile fragment");
int index = -1;
for (int i = 0; i < data.size(); i++) {
if (data.get(i).image_path.equals(user.image_path)) {
index = i;
break;
}
}
return index;
}
Userpost.java is the model here.
And here is the logcat:
java.lang.NullPointerException: Attempt to invoke interface method 'void sahhaj.com.myapp.CustomAdapter$OnItemClickListener.onItemClick(myap.com.myapp.models.Userpost, int)' on a null object reference
at sahhaj.com.sahhajapp.CustomAdapter$1.onClick(CustomAdapter.java:112)
at android.view.View.performClick(View.java:5721)
at android.view.View$PerformClick.run(View.java:22620)
Your OnItemClickListener listener attribute is never set, so it is Null.
Check where you initialize it, if ever.
Change your RecyclerView array adapter class constructor like below.
public CustomAdapter(ArrayList<Userpost> data, OnItemClickListener listener) {
this.data = data;
this.listener = listener;
}
And in your Fragment change the RecyclerView array adapter object initializing like below.
adapter = new CustomAdapter(data, new CustomAdapter.OnItemClickListener() {
#Override
public void onItemClick(Userpost userpost, int activityNumber) {
// do whatever you want to do
}
});
And that's it. Now run the code you'll get your desired output.
**Call in Get Api **
implementation "com.android.support:cardview-v7:28.0.0"
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
<uses-permission android:name="android.permission.INTERNET" />
android:usesCleartextTraffic="true"
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:id="#+id/customRecyclerView"
android:layout_height="match_parent"
/>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/coverImage"
android:layout_width="80dp"
android:layout_height="80dp" />
<TextView
android:id="#+id/title"
android:textSize="15dp"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
public interface ApiInterface
{
#GET("/photos")
Call<List<RetroPhoto>> getAllPhotos();
}
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RestApiClient {
private static Retrofit retrofit;
private static final String BASE_URL = "https://jsonplaceholder.typicode.com";
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
public class RetroPhoto {
#SerializedName("albumId")
private Integer albumId;
#SerializedName("id")
private Integer id;
#SerializedName("title")
private String title;
#SerializedName("url")
private String url;
#SerializedName("thumbnailUrl")
private String thumbnailUrl;
public RetroPhoto(Integer albumId, Integer id, String title, String url, String thumbnailUrl) {
this.albumId = albumId;
this.id = id;
this.title = title;
this.url = url;
this.thumbnailUrl = thumbnailUrl;
}
public Integer getAlbumId() {
return albumId;
}
public void setAlbumId(Integer albumId) {
this.albumId = albumId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
}
}
private CustomAdapter adapter;
private RecyclerView recyclerView;
ProgressDialog progressDoalog;
progressDoalog = new ProgressDialog(MainActivity.this);
progressDoalog.setMessage("Loading....");
progressDoalog.show();
/*Create handle for the RetrofitInstance interface*/
ApiInterface service = RestApiClient.getRetrofitInstance().create(ApiInterface.class);
Call<List<RetroPhoto>> call = service.getAllPhotos();
call.enqueue(new Callback<List<RetroPhoto>>() {
#Override
public void onResponse(Call<List<RetroPhoto>> call, Response<List<RetroPhoto>> response) {
progressDoalog.dismiss();
generateDataList(response.body());
}
#Override
public void onFailure(Call<List<RetroPhoto>> call, Throwable t) {
progressDoalog.dismiss();
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
}
/*Method to generate List of data using RecyclerView with custom adapter*/
private void generateDataList(List<RetroPhoto> photoList) {
recyclerView = findViewById(R.id.customRecyclerView);
adapter = new CustomAdapter(this, photoList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.List;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {
private List<RetroPhoto> dataList;
private Context context;
public CustomAdapter(Context context,List<RetroPhoto> dataList){
this.context = context;
this.dataList = dataList;
}
class CustomViewHolder extends RecyclerView.ViewHolder {
public final View mView;
TextView txtTitle;
private ImageView coverImage;
CustomViewHolder(View itemView) {
super(itemView);
mView = itemView;
txtTitle = mView.findViewById(R.id.title);
coverImage = mView.findViewById(R.id.coverImage);
}
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.custom_row, parent, false);
return new CustomViewHolder(view);
}
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
holder.txtTitle.setText(dataList.get(position).getTitle());
Picasso.get().load(dataList.get(position).getThumbnailUrl()).into(holder.coverImage);
// Picasso.Builder builder = new Picasso.Builder(context);
// builder.downloader(new OkHttp3Downloader(context));
// builder.build().load(dataList.get(position).getThumbnailUrl())
// .placeholder((R.drawable.ic_launcher_background))
// .error(R.drawable.ic_launcher_background)
// .into(holder.coverImage);
}
#Override
public int getItemCount() {
return dataList.size();
}
}
Image
I have an EditText which adds items to this RecyclerView and to the Realm DB. That works fine. The problem is that I don't know how to remove those items from both the RecyclerView and from the Realm DB. Should this be done on the Fragment or on the adapter? And how? Thanks!
There is an image on top showing a screenshot of the app.
Here is the Fragment where the RecyclerView is:
public class FragmentMyList extends Fragment{
private RecyclerView recyclerView;
private EditText editTxt;
private FloatingActionButton btn;
private Item item;
private ArrayList<Item> itemList;
private AdapterItemsRecycler adapterItemsRecycler;
private Realm realm;
RealmResults<Item> results;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View vistaADevolver = inflater.inflate(R.layout.fragment_my_list, container, false);
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Realm.init(getContext());
realm = Realm.getDefaultInstance();
editTxt = (EditText)vistaADevolver.findViewById(R.id.editText);
btn = (FloatingActionButton) vistaADevolver.findViewById(R.id.button);
recyclerView = (RecyclerView) vistaADevolver.findViewById(R.id.recyclerViewToDo);
itemList = new ArrayList<>();
results = realm.where(Item.class).equalTo("id", 1).findAll();
final InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
adapterItemsRecycler = new AdapterItemsRecycler(results, getActivity(), new ItemsListener());
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new SimpleItemDivider(getActivity()));
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(),LinearLayoutManager.VERTICAL, false));
recyclerView.setAdapter(adapterItemsRecycler);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String itemName = editTxt.getText().toString();
saveIntoDatabase(itemName);
inputManager.hideSoftInputFromWindow(getView().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
editTxt.getText().clear();
adapterItemsRecycler.notifyDataSetChanged();
}
});
return vistaADevolver;
}
#Override
public void onDestroy() {
super.onDestroy();
realm.close();
}
private void saveIntoDatabase(final String itemName) {
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm bgRealm) {
item = bgRealm.createObject(Item.class);
item.setName(itemName);
item.setPoint(itemName);
item.setId(1);
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putString("POINT", item.getPoint());
fragment.setArguments(bundle);
itemList.add(item);
}
}, new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
// Transaction was a success.
Log.v("database", "Stored ok");
}
}, new Realm.Transaction.OnError() {
#Override
public void onError(Throwable error) {
// Transaction failed and was automatically canceled.
Log.e("database", error.getMessage());
}
});
}
class ItemsListener implements AdapterView.OnClickListener{
#Override
public void onClick(View view) {
Item itemTouched = results.get(recyclerView.getChildAdapterPosition(view));
EscuchadorInterface unEscuchador = (EscuchadorInterface)getActivity();
unEscuchador.itemSelected(itemTouched);
}
}
public interface EscuchadorInterface{
public void itemSelected(Item anItem);
}
}
My RecyclerView adapter:
public class AdapterItemsRecycler extends RecyclerView.Adapter {
private RealmResults<Item> itemList;
private Context context;
private View.OnClickListener listener;
private Realm realm;
public AdapterItemsRecycler(RealmResults<Item> itemList, Context context, View.OnClickListener listener) {
this.itemList = itemList;
this.context = context;
this.listener = listener;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.my_list_detail, parent, false);
view.setOnClickListener(listener);
ItemViewHolder itemViewHolder = new ItemViewHolder(view);
return itemViewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Item item = itemList.get(position);
ItemViewHolder itemViewHolder = (ItemViewHolder) holder;
itemViewHolder.loadItem(item);
}
#Override
public int getItemCount() {
return itemList.size();
}
private class ItemViewHolder extends RecyclerView.ViewHolder{
private TextView itemText;
private ImageButton imageButton;
public ItemViewHolder(View view) {
super(view);
itemText = (TextView) view.findViewById(R.id.textViewItemNameTD);
imageButton = (ImageButton) view.findViewById(R.id.delete);
}
public void loadItem(Item item) {
itemText.setText(item.getName());
imageButton.setImageResource(R.drawable.trash);
}
public ImageButton getImageButton() {
return imageButton;
}
}
}
RecyclerView's detail:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:design="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:context="com.segunfamisa.sample.bottomnav.MainActivity">
<ImageButton
android:id="#+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tint="#03A9F4"
android:scaleType="centerInside"
android:background="#ffffff"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:onClick="deleteItem"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textViewItemNameTD"
android:textSize="14dp"
android:textColor="#212121"
android:background="#ffffff"
android:padding="10dp"
android:layout_toRightOf="#+id/delete"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/arrow"
android:scaleType="centerInside"
android:background="#ffffff"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>
</RelativeLayout>
Just use RealmRecyclerViewAdapter with the RealmResults directly, which handles synchronization between database and list and adapter automatically.
public class FragmentMyList
extends Fragment {
private RecyclerView recyclerView;
private EditText editTxt;
private FloatingActionButton btn;
private AdapterItemsRecycler adapterItemsRecycler;
private Realm realm;
RealmResults<Item> results;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View vistaADevolver = inflater.inflate(R.layout.fragment_my_list, container, false);
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Realm.init(getContext());
realm = Realm.getDefaultInstance();
editTxt = (EditText) vistaADevolver.findViewById(R.id.editText);
btn = (FloatingActionButton) vistaADevolver.findViewById(R.id.button);
recyclerView = (RecyclerView) vistaADevolver.findViewById(R.id.recyclerViewToDo);
results = realm.where(Item.class).equalTo("id", 1).findAll();
final InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
adapterItemsRecycler = new AdapterItemsRecycler(results, new ItemsListener());
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new SimpleItemDivider(getActivity()));
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
recyclerView.setAdapter(adapterItemsRecycler);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String itemName = editTxt.getText().toString();
saveIntoDatabase(itemName);
inputManager.hideSoftInputFromWindow(getView().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
editTxt.getText().clear();
}
});
return vistaADevolver;
}
#Override
public void onDestroy() {
super.onDestroy();
realm.close();
}
private void saveIntoDatabase(final String itemName) {
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm bgRealm) {
Item item = bgRealm.createObject(Item.class);
item.setName(itemName);
item.setPoint(itemName);
item.setId(1);
}
}, new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
// Transaction was a success.
Log.v("database", "Stored ok");
}
}, new Realm.Transaction.OnError() {
#Override
public void onError(Throwable error) {
// Transaction failed and was automatically canceled.
Log.e("database", error.getMessage());
}
});
}
class ItemsListener
implements AdapterView.OnClickListener {
#Override
public void onClick(View view) {
Item itemTouched = results.get(recyclerView.getChildAdapterPosition(view));
EscuchadorInterface unEscuchador = (EscuchadorInterface) getActivity();
unEscuchador.itemSelected(itemTouched);
}
}
public interface EscuchadorInterface {
public void itemSelected(Item anItem);
}
}
// compile 'io.realm:android-adapters:2.0.0'
public class AdapterItemsRecycler
extends RealmRecyclerViewAdapter<Item, ItemViewHolder> {
private View.OnClickListener listener;
public AdapterItemsRecycler(OrderedRealmCollection<Item> itemList, View.OnClickListener listener) {
super(itemList, true);
this.listener = listener;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.my_list_detail, parent, false);
view.setOnClickListener(listener);
ItemViewHolder itemViewHolder = new ItemViewHolder(view);
return itemViewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Item item = getData().get(position);
ItemViewHolder itemViewHolder = (ItemViewHolder) holder;
itemViewHolder.loadItem(item);
}
private static class ItemViewHolder
extends RecyclerView.ViewHolder {
private TextView itemText;
private ImageButton imageButton;
public ItemViewHolder(View view) {
super(view);
itemText = (TextView) view.findViewById(R.id.textViewItemNameTD);
imageButton = (ImageButton) view.findViewById(R.id.delete);
}
public void loadItem(Item item) {
itemText.setText(item.getName());
imageButton.setImageResource(R.drawable.trash);
}
public ImageButton getImageButton() {
return imageButton;
}
}
}
private void deleteFromDatabase(final String itemName) {
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm bgRealm) {
Item item = bgRealm.where(Item.class).equalTo("name", itemName).findFirst();
if(item != null) {
item.deleteFromRealm();
}
}
}, new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
// Transaction was a success.
Log.v("database", "Delete ok");
}
}, new Realm.Transaction.OnError() {
#Override
public void onError(Throwable error) {
// Transaction failed and was automatically canceled.
Log.e("database", error.getMessage());
}
});
}