I used techniques given in other answers like downgrading the versions of dependencies to 24... and 25.0.1.Did not work.I have width and height of RecyclerView as match_parent.
Following is the code.I am using RecyclerView for post title and post description in a blog app:
package com.awani.pocketblog;
import android.content.ClipData;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import org.w3c.dom.Text;
public class MainActivity extends AppCompatActivity {
private RecyclerView mBlogList;
private DatabaseReference mDatabase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBlogList = (RecyclerView) findViewById(R.id.blog_list);
mBlogList.setHasFixedSize(true);
mBlogList.setLayoutManager(new LinearLayoutManager(this));
mDatabase = FirebaseDatabase.getInstance().getReference().child("Blog");
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter<Blog,BlogViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Blog, BlogViewHolder>( Blog.class,
R.layout.blog_row,
BlogViewHolder.class,
mDatabase
) {
#Override
protected void populateViewHolder(BlogViewHolder viewHolder, Blog model, int position) {
viewHolder.setTitle(model.getTitle());//model means Blog class over here
viewHolder.setDesc(model.getDesc());
}
};
mBlogList.setAdapter(firebaseRecyclerAdapter);
}
//holder for the recyclerView
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_description = (TextView) mView.findViewById(R.id.post_description);
post_description.setText(desc);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu,menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==R.id.action_add){
startActivity(new Intent(MainActivity.this,PostActivity.class));
}
return super.onOptionsItemSelected(item);
}
}
log cat statement which might be causing this..
07-08 17:22:10.761 23308-23308/com.awani.pocketblog W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
this is activity_main.xml code:
<?xml version="1.0" encoding="utf-8"?>
<android.widget.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="com.awani.pocketblog.MainActivity">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/blog_list">
</android.support.v7.widget.RecyclerView>
</android.widget.RelativeLayout>
My android studio version is 2.3.2 and he dependencies are 25.3.1
and firebase dependencies are 10.0.1
firebase ui dependency 1.1.1
Check this out. I am using this code to print saved news
You can check this out for reference
Although I used fragment you can change your code accordingly for Activity.
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.example.student.newsapp.R;
import com.firebase.client.Firebase;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
public class show extends AppCompatActivity {
RecyclerView recyclerView;
FirebaseDatabase firebaseDatabase;
DatabaseReference myRef;
FirebaseAuth firebaseauth;
private FirebaseRecyclerAdapter<show_items, ShowDataViewHolder> mFirebaseAdapter;
private ProgressDialog progressDialog;
public show() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rvforbookmarks);
Firebase.setAndroidContext(this);
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Please wait..");
progressDialog.show();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Bookmarks");
firebaseDatabase = FirebaseDatabase.getInstance();
firebaseauth = FirebaseAuth.getInstance();
final String userid =firebaseauth.getCurrentUser().getUid();
// myRef = firebaseDatabase.getReference("User_Details");
myRef = FirebaseDatabase.getInstance().getReference("User_Details").child(userid);
recyclerView = (RecyclerView)findViewById(R.id.rv);
recyclerView.setLayoutManager(new LinearLayoutManager(show.this));
}
//View Holder For Recycler View
public static class ShowDataViewHolder extends RecyclerView.ViewHolder {
private final TextView image_title ;
private final ImageView image_url;
private TextView imge_des;
private ImageView btn_delete;
private TextView nobookmark;
public ShowDataViewHolder(final View itemView)
{
super(itemView);
image_url = (ImageView) itemView.findViewById(R.id.fetch_image);
image_title = (TextView) itemView.findViewById(R.id.fetch_image_title);
imge_des = (TextView) itemView.findViewById(R.id.fetch_description);
btn_delete = (ImageView) itemView.findViewById(R.id.btn_delete);
nobookmark = (TextView) itemView.findViewById(R.id.nobookmark);
}
private void Image_Title(String title)
{
image_title.setText(title);
}
private void Image_URL(String title)
{
// image_url.setImageResource(R.drawable.loading);
Glide.with(itemView.getContext())
.load(title)
.crossFade()
.placeholder(R.drawable.loading)
.thumbnail(0.1f)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(image_url);
}
public void Image_Des(String title) {
imge_des.setText(title);
}
}
#Override
public void onStart() {
super.onStart();
mFirebaseAdapter = new FirebaseRecyclerAdapter<show_items, ShowDataViewHolder>(show_items.class, R.layout.showbookamrks, ShowDataViewHolder.class, myRef) {
public void populateViewHolder(final ShowDataViewHolder viewHolder, show_items model, final int position) {
viewHolder.Image_URL(model.getImage_URL());
viewHolder.Image_Title(model.getImage_Title());
viewHolder.Image_Des(model.getImage_des());
//OnClick Item
viewHolder.btn_delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(show.this);
builder.setMessage("Do you want to Delete this data ?").setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
int selectedItems = position;
mFirebaseAdapter.getRef(selectedItems).removeValue();
mFirebaseAdapter.notifyItemRemoved(selectedItems);
recyclerView.invalidate();
onStart();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog dialog = builder.create();
dialog.setTitle("Confirm");
dialog.show();
}
});
progressDialog.dismiss();
}
};
recyclerView.setAdapter(mFirebaseAdapter);
}
}
Hope it helps
Thankyou
Follow This Example Step by Step
public class MainActivity extends AppCompatActivity implements RecyclerViewClickListener {
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_area_list);
recyclerView=(RecyclerView)findViewById(R.id.recycler_view1);
populateRecyclerView();
recyclerView.setHasFixedSize(true);
GridLayoutManager layoutManager = new GridLayoutManager(AreaListActivity.this,3);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(AreaListActivity.this, layoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.setLayoutManager(layoutManager);
//recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
// recyclerView.setLayoutManager(new GridLayoutManager(this,3));
// recyclerView.getLayoutManager().scrollToPosition(5);
}
public void populateRecyclerView(){
//pass the allAreaList to it
RecyclerViewAdapter adapter=new RecyclerViewAdapter(AreaListActivity.this,ArrayList,this);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
//recyclerView.setAdapter(new RecyclerViewAdapter(MainActivity.this,this));
}
#Override
public void recyclerViewListClicked(View v, int position) {
Intent myIntent=new Intent(MainActivity.this,SecondActivity.class);
myIntent.putExtra("position",position);
startActivity(myIntent);
finish();
}
#Override
public void onBackPressed() {
Intent myIntent=new Intent(MainActivity.this,HomeActivity.class);
startActivity(myIntent);
finish();
}
}
RecyclerViewHolder Class
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
//view holder is for girdview as we used in the listView
public ImageView imageView,imageView2;
public RecyclerViewHolder(View itemView) {
super(itemView);
this.imageView=(ImageView)itemView.findViewById(R.id.image);
}
}
Adapter Class
public class RecyclerView_Adapter extends RecyclerView.Adapter {
//RecyclerView will extend to recayclerview Adapter
private ArrayList<ModelClass> arrayList;
private Context context;
private static RecyclerViewClickListener itemListener;
//constructor of the RecyclerView Adapter
RecyclerView_Adapter(Context context,ArrayList<ModelClass> arrayList,RecyclerViewClickListener itemListener){
this.context=context;
this.arrayList=arrayList;
this.itemListener=itemListener;
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//this method will inflate the custom layout and return as viewHolder
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
ViewGroup mainGroup=(ViewGroup) layoutInflater.inflate(R.layout.single_item,parent,false);
RecyclerViewHolder listHolder=new RecyclerViewHolder(mainGroup);
return listHolder;
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, final int position) {
final ModelClass modelClass=arrayList.get(position);
//holder
RecyclerViewHolder mainHolder=(RecyclerViewHolder)holder;
//convert the drawable image into bitmap
Bitmap image= BitmapFactory.decodeResource(context.getResources(),modelClass.getImage());
//set the image into imageView
mainHolder.imageView.setImageBitmap(image);
//to handle on click event when clicked on the recyclerview item and
// get it through the RecyclerViewHolder class we have defined the views there
mainHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//get the position of the image which is clicked
itemListener.recyclerViewListClicked(v,position);
}
});
}
#Override
public int getItemCount() {
return (null!=arrayList?arrayList.size():0);
}
}
Interface
public interface RecyclerViewClickListener {
//this is method to handle the event when clicked on the image in Recyclerview
public void recyclerViewListClicked(View v,int position);
}
//and to call this method in activity
RecyclerView_Adapter adapter=new RecyclerView_Adapter(Wallpaper.this,arrayList,this);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
#Override
public void recyclerViewListClicked(View v,int position){
imageView.setImageResource(wallpaperImages[position]);
}
Related
I'm creating a TripAdvisor clone app that gets data from a Firebase database and shows data from it. I want to add a listener to the RecyclerView that opens a new Activity called locationInDetailActivity that shows informations about the picked element. Here are the codes for the MainActivity and the RecyclerView adapter.
MainActivity.java
package com.example.progettocv19ingsw;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
public class MainActivity extends AppCompatActivity {
private Button to_advanced_filters;
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
private DatabaseReference reference;
private RecyclerViewAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
to_advanced_filters = (Button) findViewById(R.id.advancedFilters);
recyclerView = findViewById(R.id.locationRecyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
to_advanced_filters.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openAdvancedFilterActivity();
}
});
reference = FirebaseDatabase.getInstance().getReference();
FirebaseRecyclerOptions<locationClass> options = new FirebaseRecyclerOptions.Builder<locationClass>().setQuery(FirebaseDatabase.getInstance().getReference().child("locations"), locationClass.class).build();
adapter = new RecyclerViewAdapter(options);
recyclerView.setAdapter(adapter);
}
public void openAdvancedFilterActivity(){
Intent open = new Intent(this, AdvancedFilters.class);
startActivity(open);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
RecyclerViewAdapter.java
package com.example.progettocv19ingsw;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
public class RecyclerViewAdapter extends FirebaseRecyclerAdapter<locationClass, RecyclerViewAdapter.myViewHolder> {
private static final String TAG = "RecyclerView";
public RecyclerViewAdapter(#NonNull FirebaseRecyclerOptions options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull myViewHolder viewHolder, int i, #NonNull locationClass location) {
viewHolder.locationName.setText(location.getLocationName());
viewHolder.locationType.setText(location.getLocationType());
Glide.with(viewHolder.locationImage.getContext()).load(location.getLocationPic()).into(viewHolder.locationImage);
viewHolder.reviewNumber.setText(String.valueOf(location.getReviewNumber()));
viewHolder.averageRatingBar.setRating(location.getAverageRating());
viewHolder.averageRatingBar.setStepSize(location.getAverageRating());
}
#Override
public int getItemCount() {
return super.getItemCount();
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.location_recyclerrow, parent, false);
return new myViewHolder(v);
}
class myViewHolder extends RecyclerView.ViewHolder {
ImageView locationImage;
TextView locationName;
TextView locationType;
RatingBar averageRatingBar;
TextView reviewNumber;
Context context;
public myViewHolder(#NonNull View itemView) {
super(itemView);
locationImage = (ImageView) itemView.findViewById(R.id.locationPicture);
locationName = (TextView) itemView.findViewById(R.id.locationName);
locationType = (TextView) itemView.findViewById(R.id.locationType);
reviewNumber = (TextView) itemView.findViewById(R.id.reviewNumber);
averageRatingBar = (RatingBar) itemView.findViewById(R.id.averageRating);
}
}
}
locationInDetailActivity.java
package com.example.progettocv19ingsw;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class locationInDetailActivity extends AppCompatActivity {
private static final String TAG = "locationDetailActivity";
private Button toReviews;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.location_data);
Log.d(TAG, "onCreate: Started");
toReviews.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
openReviewActivity();
}
});
}
private void openReviewActivity() {
Intent intent = new Intent(this, reviewActivity.class);
}
}
I have tried adding an OnClick listener, but it either gives me "cannot resolve method" or NullPointerException() errors. What do I do?
Colin Degen is right, but you can do something more generic.
Create a interface for the clicks event:
public interface IClickListener {
void onItemClick(int position, View view);
void onItemLongClick(int position, View view);
}
Create a recycler view adapter to suit your needs:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private IClickListener clickListener;
private List<String> models;
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener {
public TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
#Override
public void onClick(View view) {
clickListener.onItemClick(getAdapterPosition(), view);
}
#Override
public boolean onLongClick(View view) {
clickListener.onItemLongClick(getAdapterPosition(), view);
return false;
}
}
public RecyclerViewAdapter(List<String> models) {
this.models = models;
}
public void setOnItemClickListener(IClickListener clickListener) {
this.clickListener = clickListener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.list_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final String model = models.get(position);
TextView textView = holder.textView;
textView.setText(model);
}
#Override
public int getItemCount() {
return models.size();
}}
Then, when you want to use your recycler view you can do something like this:
ArrayList<String> dataSource = new ArrayList<String>()
// Add some data to the dataSource
RecyclerViewAdapter adapter = new RecyclerViewAdapter(dataSource);
adapter.setOnItemClickListener(new IClickListener() {
#Override
public void onItemClick(int position, View view) {
String model = dataSource.get(position);
// Do stuff with your model like passing data to the next activity
}
});
You have to define an OnClickListener for each element in your RecyclerView.
private final OnClickListener mOnClickListener = new MyOnClickListener(){
#Override
public void onClick(final View view) {
int itemPosition = mRecyclerView.getChildLayoutPosition(view);
YourItem item = mList.get(itemPosition);
//Do stuff and start your activity
}
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.location_recyclerrow, parent, false);
view.setOnClickListener(mOnClickListener);
return new myViewHolder(v);
}
And then you pass your RecyclerView instance to the constructor of your adapter
private RecyclerView mRecyclerView;
public RecyclerViewAdapter(#NonNull FirebaseRecyclerOptions options, RecyclerView rV) {
super(options);
mRecyclerView = rV;
}
I have tried using various listeners but it wont work.
The view is being produced well and everything else other than that listener is working just fine
I am a beginner in android and am doing the Jim Wilson Plural site course.
The other activity is not a problem because i have even tried using a Toast
Adapter****strong text
package com.example.plural;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.snackbar.Snackbar;
import java.util.List;
public class NoteRecyclerAdapter extends RecyclerView.Adapter<NoteRecyclerAdapter.ViewHolder> {
private final Context mContext;
private final List<NoteInfo> mNotes;
private final LayoutInflater mLayoutInflater;
public NoteRecyclerAdapter(Context context, List<NoteInfo> notes) {
mContext = context;
mNotes = notes;
mLayoutInflater = LayoutInflater.from(mContext);
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = mLayoutInflater.inflate(R.layout.itemnotelist, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
NoteInfo note = mNotes.get(position);
holder.mTextCourse.setText(note.getCourse().getTitle());
holder.mTextTitle.setText(note.getTitle());
holder.mCurrentPosition=position;
}
#Override
public int getItemCount() {
return mNotes.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public final TextView mTextCourse;
public final TextView mTextTitle;
public int mCurrentPosition;
public ViewHolder(#NonNull View itemView) {
super(itemView);
mTextCourse = (TextView) itemView.findViewById(R.id.textcourse);
mTextTitle = (TextView) itemView.findViewById(R.id.texttitle);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent= new Intent(mContext ,NoteActivity.class);
intent.putExtra(NoteActivity.NOTE_POSITION,mCurrentPosition);
mContext.startActivity(intent);
/*int position = getLayoutPosition();
Snackbar.make(v, "Click detected on item " + position,
Snackbar.LENGTH_LONG)
.setAction("Action", null).show();*/
}
});
}
}
}
MainActivity code
package com.example.plural;
import android.content.Intent;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import java.util.List;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.List;
public class NoteListActivity extends AppCompatActivity {
private NoteRecyclerAdapter mNoteRecyclerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note_list);
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(NoteListActivity.this, NoteActivity.class);
startActivity(intent);
}
});
initializeDisplayContent();
}
#Override
protected void onResume() {
super.onResume();
mNoteRecyclerAdapter.notifyDataSetChanged();
}
private void initializeDisplayContent() {
/* final ListView listNotes = findViewById(R.id.list_notes);
List<NoteInfo> notes = DataManager.getInstance().getNotes();
ArrayAdapter<NoteInfo> adapterNotes = new ArrayAdapter<>(NoteListActivity.this,
android.R.layout.simple_list_item_1, notes);
listNotes.setAdapter(adapterNotes);
listNotes.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Intent intent = new Intent(NoteListActivity.this, NoteActivity.class);
// NoteInfo note = (NoteInfo) listNotes.getItemAtPosition(position);
intent.putExtra(NoteActivity.NOTE_POSITION, position);
startActivity(intent);
}
});*/
final RecyclerView recyclerNotes =findViewById(R.id.listnotes);
final LinearLayoutManager notesLayoutManager = new LinearLayoutManager(this);
recyclerNotes.setLayoutManager(notesLayoutManager);
List<NoteInfo> notes = DataManager.getInstance().getNotes();
mNoteRecyclerAdapter = new NoteRecyclerAdapter(this, notes);
recyclerNotes.setAdapter(mNoteRecyclerAdapter);
}
}
Use Click Listener on onBindViewHolder()
Like
`holder.view.setOnClickListener(new View.OnClickListener())
{
public void onClick(){
Intent intent= new Intent(mContext ,NoteActivity.class);
intent.putExtra(NoteActivity.NOTE_POSITION,mCurrentPosition);
startActivity(intent);
}
}`
check this model for Adapter to add the click interface
public class FavouriteAdapter extends RecyclerView.Adapter<FavouriteAdapter.CustomViewHolder> {
private Context context;
private OnItemClick onItemClick;
public FavouriteAdapter(Context context){
this.context=context;
}
#NonNull
#Override
public CustomViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view= LayoutInflater.from(context).inflate(R.layout.customView,viewGroup,false);
return new CustomViewHolder(view);
}
public void setOnItemClick(OnItemClick onItemClick){
this.onItemClick=onItemClick;
notifyDataSetChanged();
}
#Override
public void onBindViewHolder(#NonNull CustomViewHolder customViewHolder, int i) { customViewHolder.setClick(onItemClick,i);
}
#Override
public int getItemCount() {
return 6;
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public CustomViewHolder(#NonNull View itemView) {
super(itemView);
}
public void setClick(final OnItemClick onItemClick, final int i) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
notifyDataSetChanged();
onItemClick.onClick(i);
}
});
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemClick.onDelete(i);
}
});
}
}
public interface OnItemClick{
public void onClick(int position);
public void onDelete(int position);
}
}
and in main activity
mNoteRecyclerAdapter.setOnItemClick(new YourAdapter..OnItemClick() {
#Override
public void onClick(ProviderDataItem providerDataItem) {
}
#Override
public void onDelete(ProviderDataItem providerDataItem, int position) {
}
});
I just set back that attribute back to neutral and its now working....it was previously on TRUE
I am using a recycler view. I've set an OnLongClickListener() on it using a custom interface. everything works fine but when I long-press the row the app crashes with Java.lang.IndexOutOfBoundsException. while debugging I found that my array list's data is being deleted while I long-press but the recycler view is just not getting updated.
here's my code.
MainActivity.java
package com.raunak.alarmdemo4;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Switch;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.raunak.alarmdemo4.Activities.AddAlarm;
import com.raunak.alarmdemo4.Adapters.AlarmAdapter;
import com.raunak.alarmdemo4.HelperClasses.AlarmsDBhelperClass;
import com.raunak.alarmdemo4.Interfaces.AlarmRecyclerViewInterface;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements AlarmRecyclerViewInterface {
FloatingActionButton mAlarmAddButton;
RecyclerView mRecyclerView;
SQLiteDatabase db;
AlarmsDBhelperClass mAlarmsDBhelperClass;
ArrayList<String> nameArrayList,modeArrayList,repeatArrayList,hoursArrayList,minArrayList;
Switch mSwitch;
AlarmAdapter alarmAdapter = new AlarmAdapter(hoursArrayList,minArrayList,modeArrayList,repeatArrayList,nameArrayList,this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//Initializing RecyclerView & DatabaseHelperClass and the FAB button
mAlarmsDBhelperClass = new AlarmsDBhelperClass(getApplicationContext());
mAlarmAddButton = findViewById(R.id.btnAlarmADD);
mRecyclerView = findViewById(R.id.alarmList);
mSwitch = findViewById(R.id.switchONOFF);
//Initializing ArrayList
nameArrayList = new ArrayList<>();
modeArrayList = new ArrayList<>();
repeatArrayList = new ArrayList<>();
hoursArrayList = new ArrayList<>();
minArrayList = new ArrayList<>();
DividerItemDecoration itemDecoration = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(itemDecoration);
//Getting a writable reference of the Database.
db = mAlarmsDBhelperClass.getWritableDatabase();
//getAlarm(db);
getAlarm(db);
mAlarmAddButton.setImageResource(R.drawable.addalarm);
mAlarmAddButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent mIntent = new Intent(getApplicationContext(), AddAlarm.class);
startActivity(mIntent);
}
});
/* mSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b){
Toast.makeText(getApplicationContext(),"Checked !",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(),"Unchecked !",Toast.LENGTH_SHORT).show();
}
}
});*/
AlarmAdapter alarmAdapter = new AlarmAdapter(hoursArrayList,minArrayList,modeArrayList,repeatArrayList,nameArrayList,this);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
mRecyclerView.setAdapter(alarmAdapter);
mRecyclerView.setHasFixedSize(true);
}
public void getAlarm(SQLiteDatabase db) {
Cursor cursor = db.rawQuery("SELECT * FROM alarms", new String[]{});
cursor.moveToFirst();
if (cursor != null) {
do {
nameArrayList.add(cursor.getString(2));
modeArrayList.add(cursor.getString(3));
repeatArrayList.add(cursor.getString(4));
hoursArrayList.add(Integer.toString(cursor.getInt(5)));
minArrayList.add(Integer.toString(cursor.getInt(6)));
} while (cursor.moveToNext());
}
cursor.close();
}
#Override
public void onItemClick(int position) {
Toast.makeText(this, "Alarm Clicked !", Toast.LENGTH_SHORT).show();
}
#Override
public void onLongItemClick(int position) {
hoursArrayList.remove(position);
Log.d("d",""+position);
alarmAdapter.notifyItemRemoved(position);
Toast.makeText(this, ""+hoursArrayList.size(), Toast.LENGTH_SHORT).show();
}
}
my Recyclerview adapter.
package com.raunak.alarmdemo4.Adapters;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.raunak.alarmdemo4.Interfaces.AlarmRecyclerViewInterface;
import com.raunak.alarmdemo4.R;
import java.util.ArrayList;
public class AlarmAdapter extends RecyclerView.Adapter<AlarmAdapter.AlarmView> {
//Variables for the main recycler view
private ArrayList<String> hoursArrayList;
private ArrayList<String> minArrayList;
private ArrayList<String> modeArrayList;
private ArrayList<String> repeatArrayList;
private ArrayList<String> nameArrayList;
private AlarmRecyclerViewInterface mInterface;
public AlarmAdapter(ArrayList<String> hours,ArrayList<String> mins,ArrayList<String> mode,ArrayList<String> repeat,ArrayList<String> name,AlarmRecyclerViewInterface mInterface){
this.hoursArrayList = hours;
this.minArrayList = mins;
this.modeArrayList = mode;
this.nameArrayList = name;
this.repeatArrayList = repeat;
this.mInterface = mInterface;
}
#NonNull
#Override
public AlarmView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.alarm_profile,parent,false);
return new AlarmView(view);
}
#Override
public void onBindViewHolder(#NonNull AlarmView holder, int position) {
if(Integer.parseInt(hoursArrayList.get(position)) < 10 ){
holder.hours.setText("0"+hoursArrayList.get(position));
}else {
holder.hours.setText(hoursArrayList.get(position));
}
if (Integer.parseInt(minArrayList.get(position)) < 10){
holder.mins.setText("0"+minArrayList.get(position));
}else {
holder.mins.setText(minArrayList.get(position));
}
holder.repeat.setText(repeatArrayList.get(position));
holder.mode.setText(modeArrayList.get(position));
holder.name.setText(nameArrayList.get(position));
}
#Override
public int getItemCount() {
return nameArrayList.size();
}
/*ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
nameArrayList.remove(viewHolder.getAdapterPosition());
modeArrayList.remove(viewHolder.getAdapterPosition());
repeatArrayList.remove(viewHolder.getAdapterPosition());
hoursArrayList.remove(viewHolder.getAdapterPosition());
minArrayList.remove(viewHolder.getAdapterPosition());
}
};*/
public class AlarmView extends RecyclerView.ViewHolder{
TextView hours,mins,repeat,name,mode;
public AlarmView(#NonNull View itemView) {
super(itemView);
hours = itemView.findViewById(R.id.txtHOUR);
mins = itemView.findViewById(R.id.txtMins);
repeat = itemView.findViewById(R.id.txtRepeatDays);
name = itemView.findViewById(R.id.txtName);
mode = itemView.findViewById(R.id.txtMode);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("d",""+getAdapterPosition());
mInterface.onItemClick(getAdapterPosition());
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
Log.d("d",""+getAdapterPosition());
mInterface.onLongItemClick(getAdapterPosition());
return true;
}
});
}
}
}
my CustomInterface
package com.raunak.alarmdemo4.Interfaces;
public interface AlarmRecyclerViewInterface {
void onItemClick(int position);
void onLongItemClick(int position);
}
Thanks for help!
You should remove the element also from nameArrayList and inside your Adapter:
#Override
public int getItemCount() {
return nameArrayList.size(); //This return a number that is higher than the number of elements
}
.
//When you call this, you remove the element from the list in the Main Activity, but not in your Adapter
hoursArrayList.remove(position);
.
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
int pos = getAdapterPosition();
Log.d("d",""+ pos);
hoursArrayList.remove(pos); //I think you'd add
nameArrayList.remove(pos); //these two lines
mInterface.onLongItemClick(pos);
return true;
}
});
.
#Override
public int getItemCount() {
return hoursArrayList.size(); //Or just the first line and modify this
}
And you should modify your MainActiivty fields:
FloatingActionButton mAlarmAddButton;
RecyclerView mRecyclerView;
SQLiteDatabase db;
AlarmsDBhelperClass mAlarmsDBhelperClass;
ArrayList<String> nameArrayList,modeArrayList,repeatArrayList,hoursArrayList,minArrayList;
Switch mSwitch;
AlarmAdapter alarmAdapter = new AlarmAdapter(hoursArrayList,minArrayList,modeArrayList,repeatArrayList,nameArrayList,this);
//This line has nosense, if you re-declare another alarmAdapter in the onCreate
Your are declaring and assigning different adapter in onCreate. Remove the declaration from there and just initialize it there.
AlarmAdapter alarmAdapter = new AlarmAdapter(hoursArrayList,minArrayList,modeArrayList,repeatArrayList,nameArrayList,this);
And you need to improve your code for efficiency, create a model class instead of declaring arrrayList of every param.
I use this code in MainActivity But I can not access setOnMenuItemClickListener in MainActivity .
MainActivity class:
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.ImageView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
Toast toast ;
ImageView hahaha;
protected static int ss=77;
//recyclerview objects
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
public int xxx=222;
//model object for our list data
private List<MyList> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//initializing views
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<>();
//loading list view item with this function
loadRecyclerViewItem();
}
private void loadRecyclerViewItem() {
//you can fetch the data from server or some apis
//for this tutorial I am adding some dummy data directly
for (int i = 1; i <= 7; i++) {
MyList myList = new MyList(
"Heading " + i,
"id = " + i,
"https://mediaresources.idiva.com/media//content/2014/May/diet_kids_health1.jpg",
"HHHHHH" + i
);
list.add(myList);
}
adapter = new CustomAdapter(list, this);
recyclerView.setAdapter(adapter);
}
}
and this is CustomAdaptor.class
import android.content.Context;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.List;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private List<MyList> list;
private Context mCtx;
public CustomAdapter(List<MyList> list, Context mCtx) {
this.list = list;
this.mCtx = mCtx;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_items, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(final CustomAdapter.ViewHolder holder, final int position) {
MyList myList = list.get(position);
//loading the image
Glide.with(mCtx)
.load(myList.getUrl())
.into(holder.imageView);
holder.textViewHead.setText(myList.getHead());
holder.textViewDesc.setText(myList.getDesc());
//holder.textViewDesc.setText(myList.getIdofdata());
holder.buttonViewOption.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//creating a popup menu
PopupMenu popup = new PopupMenu(mCtx, holder.buttonViewOption);
//inflating menu from xml resource
popup.inflate(R.menu.options_menu);
//adding click listener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu1:
//handle menu1 click
holder.textViewHead.setText("moshiri" + holder.textViewHead.getText() );
break;
case R.id.menu2:
//holder.textViewHead.setText("new" + holder.textViewDesc.getText() );
holder.textViewHead.setText("mohsen hi dear");
break;
case R.id.menu3:
holder.textViewHead.setText("##################" + list.indexOf(this));
holder.textViewDesc.setText("############" + list.indexOf(this));
//MainActivity me=new MainActivity();
MainActivity.ss=77;
removeItem(3);
break;
}
return false;
}
});
//displaying the popup
popup.show();
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public void removeItem(int position) {
list.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, getItemCount() );
// notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewHead;
public TextView textViewDesc;
public TextView buttonViewOption;
public ImageView imageView;
public ViewHolder(View itemView) {
super(itemView);
textViewHead = (TextView) itemView.findViewById(R.id.textViewHead);
textViewDesc = (TextView) itemView.findViewById(R.id.textViewDesc);
buttonViewOption = (TextView) itemView.findViewById(R.id.textViewOptions);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
}
}
}
In CustomAdaptor I access onclick listener in menu and button but I can not manage menu and button in MainActivity. How can I use Listener in mainActivity or how can I send changes from CustomAdaptor to mainActivity?
Use interface for this purpose. In your CustomAdapter declare that interface and in ViewHolder override the click listener method and pass items from adapter you want. Currently I am passing position only you can pass anything here. I have make changes in your code just check below.
import android.content.Context;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.List;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
protected CustomClicklistener mListener;
private List<MyList> list;
private Context mCtx;
private CustomClicklistener clickListener;
public interface CustomClicklistener {
void onItemClick(int position);
}
public CustomAdapter(List<MyList> list, Context mCtx, CustomClicklistener
clickListener) {
this.list = list;
this.mCtx = mCtx;
this.clickListener = clickListener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_items, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(final CustomAdapter.ViewHolder holder, final int position) {
MyList myList = list.get(position);
//loading the image
Glide.with(mCtx)
.load(myList.getUrl())
.into(holder.imageView);
holder.textViewHead.setText(myList.getHead());
holder.textViewDesc.setText(myList.getDesc());
//holder.textViewDesc.setText(myList.getIdofdata());
holder.buttonViewOption.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//creating a popup menu
PopupMenu popup = new PopupMenu(mCtx, holder.buttonViewOption);
//inflating menu from xml resource
popup.inflate(R.menu.options_menu);
//adding click listener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu1:
//handle menu1 click
holder.textViewHead.setText("moshiri" + holder.textViewHead.getText() );
break;
case R.id.menu2:
//holder.textViewHead.setText("new" + holder.textViewDesc.getText() );
holder.textViewHead.setText("mohsen hi dear");
break;
case R.id.menu3:
holder.textViewHead.setText("##################" + list.indexOf(this));
holder.textViewDesc.setText("############" + list.indexOf(this));
//MainActivity me=new MainActivity();
MainActivity.ss=77;
removeItem(3);
break;
}
return false;
}
});
//displaying the popup
popup.show();
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public void removeItem(int position) {
list.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, getItemCount() );
// notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView textViewHead;
public TextView textViewDesc;
public TextView buttonViewOption;
public ImageView imageView;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
textViewHead = (TextView) itemView.findViewById(R.id.textViewHead);
textViewDesc = (TextView) itemView.findViewById(R.id.textViewDesc);
buttonViewOption = (TextView) itemView.findViewById(R.id.textViewOptions);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
}
#Override
public void onClick(View view) {
if (mListener != null) {
mListener.onItemClick(getAdapterPosition());
notifyDataSetChanged();
}
}
}
}
In MainActivity you can get that clicklistener like below in oncCreate METHOD AT THE END
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.ImageView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
CustomAdapter.CustomClicklistener clickListener;
Toast toast ;
ImageView hahaha;
protected static int ss=77;
//recyclerview objects
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
public int xxx=222;
//model object for our list data
private List<MyList> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//initializing views
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<>();
//loading list view item with this function
loadRecyclerViewItem();
clickListener = new CustomAdapter.CustomClicklistener() {
#Override
public void onItemClick(int position) {
// Do what you want here
Toast.makeText(MainActivity.this, "This ... " , Toast.LENGTH_LONG).show();
}
};
}
private void loadRecyclerViewItem() {
//you can fetch the data from server or some apis
//for this tutorial I am adding some dummy data directly
for (int i = 1; i <= 7; i++) {
MyList myList = new MyList(
"Heading " + i,
"id = " + i,
"https://media.alalamtv.net/news/image/855x495//2015/02/16/alalam_635596703961833722_25f_4x3.jpg",
"HHHHHH" + i
);
list.add(myList);
}
adapter = new CustomAdapter(list, this, clickListener);
recyclerView.setAdapter(adapter);
}
}
Create an interface in your CustomAdapter class like:
CustomAdapterListener customAdapterListener;
public interface CustomAdapterListener {
void onItemClick();
}
And then in your constructor :
public CustomAdapter(List<MyList> list, Context mCtx, CustomAdapterListener customAdapterListener) {
this.list = list;
this.mCtx = mCtx;
this.customAdapterListener= customAdapterListener;
}
and trigger interface method when click event occured:
holder.buttonViewOption.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
customAdapterListener.onItemClick();
});
And from your Activity; add your activity as listener like this :
adapter = new CustomAdapter(list, this, this);
Finally you have to implement your interface in your activity like :
public class MainActivity extends AppCompatActivity implements CustomAdapter.CustomAdapterListener
And click on red underlined text and press alt+enter, this will suggest you to implement interface methods, after confirm that warning you have onItemClick method in your activity. This method will trigger from adapter if click event is occured.
I am working with a RecyclerView and I am trying to set OnClick's and OnLongClick's for each of the item's in the RecyclerView. I apologize but I don't think I truly understand what is going on with the code, some of it was taken off slides for my assignment and some patches for stuff that wouldn't work that I found on this site. At the top of my RecyclerView Adapter class I hav
static OnItemClickListener mItemClickListener;` And then I have an interface for my new methods, a method to set my clicklistener, and then my ViewHolder implementation like so:
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView movieImage;
public TextView movieName;
public TextView movieDescription;
public CheckBox movieCheckBox;
public CardView cV;
public ViewHolder(View view) {
super(view);
movieImage = (ImageView) view.findViewById(R.id.movieImg);
movieName = (TextView) view.findViewById(R.id.movieName);
movieDescription = (TextView) view.findViewById(R.id.movieDescription);
movieCheckBox = (CheckBox) view.findViewById(R.id.movieCheckBox);
view.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
if (mItemClickListener != null) {
if (getAdapterPosition() != RecyclerView.NO_POSITION) {
mItemClickListener.onItemClick(v, getAdapterPosition());
}
}
}
});
view.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (mItemClickListener != null) {
if (getAdapterPosition() != RecyclerView.NO_POSITION) {
mItemClickListener.onItemLongClick(v, getAdapterPosition());
}
}
return true;
}
});
}
}
My issue comes in the class for my fragment which owns the recycler view, where I am trying to set the onitemclicklistener.
myAdapter = new MyRecyclerAdapter();
myAdapter.setOnItemClickListener(new MyRecyclerAdapter.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Log.d("TEST", "onItemClick");
}
#Override
public void onItemLongClick(View view, int position) {
Log.d("TEST", "onItemLongClick");
}
});
It says the issue is with myAdapter.setOnItemClickListener it says 'Cannot resolve method 'setOnItemClickListener(anonymous com.example.kevin.assignment4.MyRecyclerAdapter.OnItemClickListener)' But I don't know why it's saying that. It should be able to find the method just fine as far as I can tell. EDIT: My imports for MyRecyclerView class are as follows:
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.HashMap;
I tried same thing and its working cool. check this.
public class MyFragment extends BaseFragment implements SwipeRefreshLayout.OnRefreshListener{
private MyAdapter mAdapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
setHasOptionsMenu(true);
//init views
final View root = inflater.inflate(R.layout.layout, container, false);
RecyclerView rv = (RecyclerView) root.findViewById(R.id.recyclerview);
mAdapter = new MyAdapter(getActivity(), data);
mAdapter.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Toast.makeText(getActivity(), "Working...", Toast.LENGTH_LONG).show();
}
});
rv.setAdapter(mAdapter);
rv.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL));
return root;
}
public interface OnItemClickListener{
void onItemClick(View view, int position);
}
private class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<Data> data;
private Context mContext;
MyAdapter(Context context, ArrayList<Data> data) {
this.data = data;
}
private OnItemClickListener onItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemClickListener = onItemClickListener;
}
class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
MyHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(onItemClickListener != null){
onItemClickListener.onItemClick(v, getAdapterPosition());
}
}
}
}
}
I'm way too late but this might help someone; I've just had the same 'cannot resolve symbol' issue while trying to use the Adapter's custom methods from an activity (in order to set up click listeners for RecyclerView in Java, using Android Studio 3.3.2).
Confusingly, despite this, at the same time, for my adapter instance the base class RecyclerView.Adapter's own methods (such as getItemCount and onBindViewHolder ) were resolvable.
My problem was that I had similar to Kevin's code, where Kevin in his fragment has:
myAdapter = new MyRecyclerAdapter();
whereas what solved my problem was that I had neglected to simply specify a type when instantiating the Adapter - e.g.:
MyRecyclerAdapter myAdapter = new MyRecyclerAdapter();
... 'cannot resolve symbol' then became a thing of the past and I was able to access my custom Adapter methods such as setOnItemClickedListener.
So I'm not sure why my original method didn't work, since I've seen similar methods online and even one of the answers posted here worked the same way. I solved my issue by changing the structure of my adapter class so that it takes the listener in as a parameter to the constructor of the RecyclerView adapter. There, I set the listener in the class equal to the listener that came in.
public MyRecyclerAdapter(ClickListener clickListener) {
setClickListener(clickListener);
}
And then in my fragment where I create the recyclerview I have
myAdapter = new MyRecyclerAdapter(this);
My fragment class implements the interface from my adapter class.
Accidentally declaring your adapter as RecyclerView.Adapter instead of your custom adapter MyRecyclerAdapter() is a possible cause.
RecyclerView.Adapter adapter = new MyRecyclerAdapter()
Instead of,
MyRecyclerAdapter adapter = new MyRecyclerAdapter()
I had the similar problem.. This code solved my problem.Its too late for answering, but this code works like magic.This is my java class.
package app.android.dgconnect.activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import app.android.dgconnect.R;
import app.android.dgconnect.adapters.AddressBookAdapter;
import app.android.dgconnect.models.CustomersProfileModel;
public class AddressBookMain extends AppCompatActivity implements AdapterView.OnItemClickListener {
private List<CustomersProfileModel> itemList = new ArrayList<>();
private AddressBookAdapter mAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.address_book_layout);
CustomersProfileModel customersProfileModel=getIntent().getParcelableExtra("customerProfileModel");
TextView title = findViewById(R.id.title);
ImageView toolbar_back = findViewById(R.id.toolbar_back);
title.setText("Address");
toolbar_back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
RecyclerView recyclerView = findViewById(R.id.recycler_view);
mAdapter = new AddressBookAdapter(itemList,this);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), LinearLayoutManager.HORIZONTAL));
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
for(int i=0;i<customersProfileModel.addresses.size();i++){
itemList.add(customersProfileModel);
mAdapter.notifyDataSetChanged();
}
mAdapter.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
This is my adapter class :
package app.android.dgconnect.adapters;
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.AdapterView;
import android.widget.RadioButton;
import android.widget.TextView;
import java.util.List;
import app.android.dgconnect.R;
import app.android.dgconnect.models.CustomersProfileModel;
public class AddressBookAdapter extends RecyclerView.Adapter<AddressBookAdapter.SingleCheckViewHolder> {
private List<CustomersProfileModel> itemList;
private int mSelectedItem = -1;
private Context mContext;
private AdapterView.OnItemClickListener onItemClickListener;
public AddressBookAdapter(List<CustomersProfileModel> itemList, Context context) {
this.itemList = itemList;
this.mContext = context;
}
#NonNull
#Override
public SingleCheckViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(mContext);
final View view = inflater.inflate(R.layout.address_book_list_row, viewGroup, false);
return new SingleCheckViewHolder(view, this);
}
#Override
public void onBindViewHolder(#NonNull final SingleCheckViewHolder holder, final int position) {
CustomersProfileModel items = itemList.get(position);
holder.address.setText(items.addresses.get(position).street.get(0));
String rname = items.addresses.get(position).region.region;
String pcode = items.addresses.get(position).postcode;
if (rname.equals("string")) {
holder.address_line_two.setText(pcode);
} else {
holder.address_line_two.setText(rname + ", " + pcode);
}
try {
holder.setDateToView(items, position);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public int getItemCount() {
return itemList.size();
}
public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public void onItemHolderClick(SingleCheckViewHolder holder) {
if (onItemClickListener != null)
onItemClickListener.onItemClick(null, holder.itemView, holder.getAdapterPosition(), holder.getItemId());
}
class SingleCheckViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private AddressBookAdapter mAdapter;
private RadioButton radioButton;
private TextView address, address_line_two;
public SingleCheckViewHolder(View itemView, final AddressBookAdapter mAdapter) {
super(itemView);
this.mAdapter = mAdapter;
address = itemView.findViewById(R.id.address);
address_line_two = itemView.findViewById(R.id.address_line_two);
radioButton = itemView.findViewById(R.id.radioButton);
itemView.setOnClickListener(this);
radioButton.setOnClickListener(this);
}
public void setDateToView(CustomersProfileModel item, int position) throws Exception {
radioButton.setChecked(position == mSelectedItem);
// mText.setText(item.getPersonName());
}
#Override
public void onClick(View v) {
mSelectedItem = getAdapterPosition();
notifyItemRangeChanged(0, itemList.size());
mAdapter.onItemHolderClick(SingleCheckViewHolder.this);
}
}
}