Cannot call method of RecyclerView adapter from an activity - java

I am trying to set the data for recycler view to display from an AsyncTask. I am calling the method setdataEntries from the postExecute of inner class AsyncTask. But the android studio is showing me error could not find the method.
Adapter class
public class EntryAdapter extends RecyclerView.Adapter<EntryAdapter.ViewHolder> {
List<UserTuple> entries;
final private itemClickListener mOnClickListener;
public interface itemClickListener{
void onItemClick(UserTuple utuple);
}
public EntryAdapter(itemClickListener clickhandler) {
mOnClickListener = clickhandler;
}
public void setdataEntries(List<UserTuple> Data) {
entries = Data;
notifyDataSetChanged();
}
#Override
public EntryAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.singleusertuple,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(EntryAdapter.ViewHolder holder, int position) {
holder.Username.setText(entries.get(position).getUsername());
holder.Password.setText(entries.get(position).getPassword());
}
#Override
public int getItemCount() {
return entries.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView Username;
private TextView Password;
private CardView card;
public ViewHolder(View itemView) {
super(itemView);
Username = itemView.findViewById(R.id.susername);
Password=itemView.findViewById(R.id.pass);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int adapterPosition = getAdapterPosition();
UserTuple ut=new UserTuple(entries.get(adapterPosition).getUsername(),entries.get(adapterPosition).getPassword());
mOnClickListener.onItemClick(ut);
}
}
}
Calling Activity
public class Usertuple extends AppCompatActivity implements EntryAdapter.itemClickListener {
private RecyclerView recyclerView ;
private RecyclerView.Adapter adapater;
private SnapHelper snapHelper;
private List<UserTuple> entries;
private ProgressBar mLoadingIndicator;
private Bundle extras;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logins);
extras = getIntent().getExtras();
//String site= extras.getString("sitename");
mLoadingIndicator = (ProgressBar) findViewById(R.id.pb_loading_indicator);
Log.i("Logins","Size of returned list "+entries.size());
recyclerView = findViewById(R.id.recycleview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
adapater = new EntryAdapter(this);
recyclerView.setAdapter(adapater);
snapHelper= new LinearSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
dataView();
}
public void dataView() {
String site= extras.getString("sitename");
recyclerView.setVisibility(View.VISIBLE);
new FetchDataTask().execute(site);
}
#Override
public void onItemClick(UserTuple utuple) {
}
private String key(){
SharedPreferences sharedPref = getSharedPreferences(
"User", this.MODE_PRIVATE);
final String passphrase = sharedPref.getString("userid", "none");
return passphrase;
}
public void showerror(){
recyclerView.setVisibility(View.GONE);
Toast.makeText(this,"Error in retrieving",Toast.LENGTH_SHORT).show();
}
public setdata(List<UserTuple> data){
adapater.setdataEntries(data);
}
public class FetchDataTask extends AsyncTask<String, Void, List<UserTuple>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mLoadingIndicator.setVisibility(View.VISIBLE);
}
#Override
protected List<UserTuple> doInBackground(String... params) {
/* If there's no zip code, there's nothing to look up. */
if (params.length == 0) {
return null;
}
String site = params[0];
try {
AppDatabase db = Room.databaseBuilder(getApplicationContext(),AppDatabase.class, "production")
.build();
entries =db.entryDao().getSpecific(site);
for(UserTuple ut : entries){
Log.i("password",ut.getPassword());
String st = new Decryption().decrypt(ut.getPassword(),key());
Log.i("After decryption",st);
ut.setPassword(st);
}
return entries;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(List<UserTuple> Data) {
mLoadingIndicator.setVisibility(View.INVISIBLE);
if (Data != null) {
adapater.setdataEntries(Data);
} else {
showerror();
}
}
}
}
I want the database calls to be a background task. I don't want the activity to freeze waiting for database calls. Any ideas? Thanks

Declare adapter like
private EntryAdapter adapter;
instead of
private RecyclerView.Adapter adapater;
because RecyclerView.Adapter class does not have any method named setdataEntries but only EntryAdapter class has this method so only the object of type EntryAdapter can call setdataEntries method.
Or you can use down-casting as
((EntryAdapter)adapater).setdataEntries(data);

Related

how to implement bottomsheetdialogfragment

There is a holder
public class ClientTivarHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView texttovarname,texttovarprice;
public RoundedImageView imageTovar;
public CardView cardTovar;
public ItemClickListener itemClickListener;
private Dialog dialog;
private Context context;
public ClientTivarHolder(View itemView){
super(itemView);
texttovarname=itemView.findViewById(R.id.texttovrnme);
texttovarprice=itemView.findViewById(R.id.pricetexttovar);
imageTovar=itemView.findViewById(R.id.tovarImage);
cardTovar=itemView.findViewById(R.id.tovarcard);
}
public void setItemClickListner(ItemClickListener listner){this.itemClickListener=listner;}
#Override
public void onClick(View view){
itemClickListener.onClick(view,getAdapterPosition(),false);
}
}
There is an adapter
public class TovarsAdapter {
private String TovarName,TovarOpisanie,TovarPrice,TovarImage,ShopPhone,ShopUid;
public TovarsAdapter(){
}
public TovarsAdapter(String tovarName, String tovarOpisanie, String tovarPrice, String tovarImage, String shopPhone, String shopUid) {
this. TovarName = tovarName;
this. TovarOpisanie = tovarOpisanie;
this. TovarPrice = tovarPrice;
this. TovarImage = tovarImage;
this. ShopPhone = shopPhone;
this. ShopUid = shopUid;
}
public String getTovarName() {
return TovarName;
}
public void setTovarName(String tovarName) {
TovarName = tovarName;
}
public String getTovarOpisanie() {
return TovarOpisanie;
}
public void setTovarOpisanie(String tovarOpisanie) {
TovarOpisanie = tovarOpisanie;
}
public String getTovarPrice() {
return TovarPrice;
}
public void setTovarPrice(String tovarPrice) {
TovarPrice = tovarPrice;
}
public String getTovarImage() {
return TovarImage;
}
public void setTovarImage(String tovarImage) {
TovarImage = tovarImage;
}
public String getShopPhone() {
return ShopPhone;
}
public void setShopPhone(String shopPhone) {
ShopPhone = shopPhone;
}
public String getShopUid() {
return ShopUid;
}
public void setShopUid(String shopUid) {
ShopUid = shopUid;
}
}
And the interface class ItemClickListener
public interface ItemClickListener {
void onClick(View view, int position, boolean isLongClick);
}
Activate itself where I want to implement it
public class TovarActivity extends AppCompatActivity {
private DatabaseReference tovars;
private RecyclerView recyclerView;
private String uid,srav;
RecyclerView.LayoutManager layoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tovar);
layoutManager=new GridLayoutManager(this,2);
Log.d("Uid",getIntent().getExtras().get("ShopUid").toString());
recyclerView=(RecyclerView) findViewById(R.id.tovarrec);
tovars= FirebaseDatabase.getInstance().getReference().child("Tovars");
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerOptions<TovarsAdapter> options=new FirebaseRecyclerOptions.Builder<TovarsAdapter>()
.setQuery(tovars.orderByChild("ShopUid").equalTo(getIntent().getExtras().get("ShopUid").toString()),TovarsAdapter.class).build();
FirebaseRecyclerAdapter<TovarsAdapter, ClientTivarHolder> adapter=new FirebaseRecyclerAdapter<TovarsAdapter, ClientTivarHolder>(options) {
#Override
protected void onBindViewHolder( #androidx.annotation.NonNull ClientTivarHolder holder, int position, #androidx.annotation.NonNull TovarsAdapter model) {
holder.texttovarprice.setText(model.getTovarPrice());
holder.texttovarname.setText(model.getTovarOpisanie());
holder.texttovarname.setHint(model.getShopUid());
Transformation transformation=new RoundedTransformationBuilder().borderColor(Color.WHITE).borderWidthDp(3).cornerRadius(12).oval(false).build();
Picasso.get().load(model.getTovarImage()).transform(transformation).into(holder.imageTovar);
}
#Override
public ClientTivarHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_tovars,parent,false);
ClientTivarHolder holder=new ClientTivarHolder(view);
return holder;
}
};
recyclerView.setAdapter(adapter);
adapter.startListening();
}
}
Problem: I don’t know how to make a listener on a separate item send a hint from it with a uid to receive certain information in the bottomsheetdialogfragmemt. I tried to make a fragment manager in the holder but it didn't work out. How can I solve my problem?
tried to make fragment manager inside holder but didn't work

recyclerView missing error in Android Studio

I'm a beginner programmer and I'm trying to receive data from the server using node.js and display the list on Android Studio but I keep having the following error:
E/RecyclerView: No adapter attached; skipping layout
D/HistoryActivity: HistoryResponse{result=[com.sooryong.loginexample.data.HistoryData#3303f3c, com.sooryong.loginexample.data.HistoryData#33764c5]}
D/AndroidRuntime: Shutting down VM
As you can see, I can't recall my list properly as well and I don't know how to fix it. Here are my codes:
public interface ServiceApi {
#POST("/user/login")
Call<LoginResponse> userLogin(#Body LoginData data);
#POST("/user/join")
Call<JoinResponse> userJoin(#Body JoinData data);
#GET("/test/history")
Call<HistoryResponse> getData();
}
HistoryData.java
public class HistoryData {
#SerializedName("eventID")
private int eventID;
#SerializedName("eventType")
private String eventType;
#SerializedName("eventDate")
private String eventDate;
#SerializedName("userID")
private int userID;
#SerializedName("sensorID")
private String sensorID;
public HistoryData(int eventID, String eventType, String eventDate, int userID, String sensorID) {
super();
this.eventID = eventID;
this.eventType = eventType;
this.eventDate = eventDate;
this.userID = userID;
this.sensorID = sensorID;
}
public int getEventID() {
return eventID;
}
public String getEventType() {
return eventType;
}
public String getEventDate() { return eventDate; }
public int getUserID() {
return userID;
}
public String getSensorID() { return sensorID; }
}
HistoryResponse.java
public class HistoryResponse {
#SerializedName("code")
public String code;
#SerializedName("message")
public String message;
#SerializedName("result")
public List<HistoryData> result;
#Override
public String toString() {
return "HistoryResponse{" + "result=" + result +'}';
}
}
HistoryActivity.java
public class HistoryActivity extends AppCompatActivity {
HistoryResponse dataList;
List<HistoryData> dataInfo;
private RecyclerView recyclerView;
private RecyclerAdapter recyclerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recycler_view);
dataInfo = new ArrayList<>();
recyclerView = findViewById(R.id.recyclerView);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
ServiceApi apiInterface = RetrofitClient.getClient().create(ServiceApi.class);
Call<HistoryResponse> call = apiInterface.getData();
call.enqueue(new Callback<HistoryResponse>() {
#Override
public void onResponse(Call<HistoryResponse> call, Response<HistoryResponse> response) {
dataList = response.body();
Log.d("Response", dataList.toString());
dataInfo = dataList.result;
recyclerAdapter = new RecyclerAdapter(getApplicationContext(), dataInfo);
recyclerView.setAdapter(recyclerAdapter);
}
#Override
public void onFailure(Call<HistoryResponse> call, Throwable t) {
Log.d("Response", t.getMessage());
}
});
}
}
RecyclerAdapter.java
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder>{
private Context c;
private List<HistoryData> dataList;
public RecyclerAdapter(Context c, List<HistoryData> dataList) {
this.c = c;
this.dataList = dataList;
}
#NonNull
#Override
public RecyclerAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(c).inflate(R.layout.recycler_view, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerAdapter.MyViewHolder holder, int position) {
holder.id.setText(dataList.get(position).getSensorID());
holder.type.setText("" + dataList.get(position).getEventType());
holder.date.setText("" + dataList.get(position).getEventDate());
}
#Override
public int getItemCount() {
return (dataList == null) ? 0 : dataList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView id;
TextView type;
TextView date;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
id = (TextView)itemView.findViewById(R.id.sensorID);
type = (TextView)itemView.findViewById(R.id.eventType);
date = (TextView)itemView.findViewById(R.id.eventDate);
}
}
}
I don't think the data is being initialized properly inside the RecyclerAdapter class. Is it because I couldn't load the data properly from the server?
I ever face the same issue similiar to this.
What I've done was: initialize the adapter once only the activity created:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recycler_view);
dataInfo = new ArrayList<>();
initAdapter();
....
}
private void initAdapter() {
//The adapter should create once in onCreate
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext, LinearLayoutManager.VERTICAL, false);
recyclerAdapter = new RecyclerAdapter(getApplicationContext(), dataInfo);
recyclerView.setAdapter(recyclerAdapter);
}
Then when in callback result: you can clear the previous data before reload to the adapter:
call.enqueue(new Callback<HistoryResponse>() {
#Override
public void onResponse(Call<HistoryResponse> call, Response<HistoryResponse> response) {
dataList = response.body();
dataInfo.clear(); // <- here we clear all previous data before reload result to the adapter.
dataInfo = dataList.result;
recyclerAdapter.notifyDataSetChanged()
#Override
public void onFailure(Call<HistoryResponse> call, Throwable t) {
Log.d("Response", t.getMessage());
}
});
Hope this help.

recyclerview for chat app doesn't show any data or views

Hi I'm building chat app UI with android but it runs without showing any data or views,
I interact with a bot server that should return text after I send a text. I'm using retrofit for http connections.
the model class showing are the response from json
please help me and ask me any details you want
My adapter
public class MessageListAdapter extends
RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int VIEW_TYPE_MESSAGE_SENT = 1;
private static final int VIEW_TYPE_MESSAGE_RECEIVED = 2;
private List<Messages> data;
private Context mContext;
// constructor
public MessageListAdapter(List<Messages> data, Context mContext) {
this.data = data;
this.mContext = mContext;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
if (viewType == VIEW_TYPE_MESSAGE_SENT) {
return new SentMessageHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.user_message, parent, false));
} else {
return new RecvdMessageHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.bot_message, parent, false));
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int type = getItemViewType(position);
Messages messages = data.get(position);
if (type == VIEW_TYPE_MESSAGE_SENT) {
SentMessageHolder sentMessageHolder = (SentMessageHolder) holder;
sentMessageHolder.messageBody.setText(messages.getText());
} else {
RecvdMessageHolder recvdMessageHolder = (RecvdMessageHolder) holder;
recvdMessageHolder.messageBody.setText(messages.getText());
}
}
public int getItemViewType(int position) {
Messages messages = data.get(position);
if (messages.getRecipientId() == ("default")) {
return VIEW_TYPE_MESSAGE_SENT;
} else
return VIEW_TYPE_MESSAGE_RECEIVED;
}
#Override
public int getItemCount() {
if (data != null) {
return data.size();
} else return 0;
}
class SentMessageHolder extends RecyclerView.ViewHolder {
public TextView messageBody;
public SentMessageHolder(View itemView) {
super(itemView);
messageBody = (TextView) itemView.findViewById(R.id.text_message_body);
}
}
class RecvdMessageHolder extends RecyclerView.ViewHolder {
public TextView messageBody;
public RecvdMessageHolder(View itemView) {
super(itemView);
messageBody = (TextView) itemView.findViewById(R.id.text_message_body);
}
}
My activity
public class MainActivity extends AppCompatActivity {
private EditText editText;
private RecyclerView mMessageRecycler;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter MessageListAdapter;
List<Messages> data;
//init client
Retrofit retrofit = RetrofitClient.getRetrofitClient();
//contact with the interface
APIService apiService = retrofit.create(APIService.class);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.my_msg);
data = new ArrayList<>();
mMessageRecycler = (RecyclerView) findViewById(R.id.reyclerview_message_list);
MessageListAdapter = new MessageListAdapter(data , this);
// messageListAdapter.notifyDataSetChanged();
mMessageRecycler.setAdapter(MessageListAdapter);
mMessageRecycler.setLayoutManager(new LinearLayoutManager(this));
mMessageRecycler.setHasFixedSize(true);
}
public void clickedbtn(View view) {
fetchMessages();
}
private void fetchMessages() {
Call<List<Messages>> res = apiService.getBotResponse(editText.getText().toString());
res.enqueue(new Callback<List<Messages>>() {
#Override
public void onResponse(Call<List<Messages>> call, Response<List<Messages>> response) {
List<Messages> messages = response.body();
data.addAll(messages);//Changed here
MessageListAdapter.notifyDataSetChanged();//Changed here
mMessageRecycler.smoothScrollToPosition(messages.size()-1);
}
#Override
public void onFailure(Call<List<Messages>> call, Throwable t) {
}
});
}
My model class
public class Messages {
#SerializedName("recipient_id")
#Expose
private String recipientId;
#SerializedName("text")
#Expose
private String text;
public Messages(String text) {
this.text = text;
}
public String getRecipientId() {
return recipientId;
}
public void setRecipientId(String recipientId) {
this.recipientId = recipientId;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
Try adding both the instantiation of the Adapter and the RecyclerView.setAdapter() to the retrofit onResponse():
Like this:
Call<List<Messages>> res = apiService.getBotResponse(editText.getText().toString());
res.enqueue(new Callback<List<Messages>>() {
#Override
public void onResponse(Call<List<Messages>> call, Response<List<Messages>> response) {
List<Messages> messages = response.body();
//Init the Adpater here!!
MessageListAdapter = new MessageListAdapter(data , this);
//SetAdapter here!!
mMessageRecycler.setAdapter(MessageListAdapter);
data.addAll(messages);//Changed here
MessageListAdapter.notifyDataSetChanged();//Changed here
mMessageRecycler.smoothScrollToPosition(messages.size()-1);
}
#Override
public void onFailure(Call<List<Messages>> call, Throwable t) {
}
});
EDIT:
In addition to the above, your clickedbtn() should look like this:
public void clickedbtn(View view) {
Messages msg = new Messages(editText.getText().toString());
msg.setRecipientId("default");
data.add(msg);
MessageListAdapter.notifyDataSetChanged();
fetchMessages();
}

How pass data from RecyclerView to activity

I need to pass data from recyclerView adapter to main activity on click on image of recyclerview. Can someone help?
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoHolder> {
private ArrayList<Video> mData;
private ArrayList<Video> mData2;
private Activity mACtivity;
public VideoAdapter(ArrayList<Video> data, ArrayList<Video> data2, Activity activity) {
this.mData = data;
this.mData2 = data2;
this.mACtivity = activity;
}
#Override
public VideoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.anteprima_list_item, parent, false);
//view.setOnClickListener(mOnClickListener);
return new VideoHolder(view);
}
#Override
public void onBindViewHolder(VideoHolder holder, int position) {
Video video = mData.get(position);
final Video video2 = mData2.get(position);
holder.setTitolo(video.getTitolo());
holder.setSottoTitolo(video.getSottotitolo());
holder.setData(video.getData());
holder.setData(video.getData());
/* holder.setAddress(restaurant.getAddress());
holder.setCost("Average cost for 2: " + restaurant.getCurrency() + restaurant.getCost());
holder.setRating(restaurant.getRating());*/
Glide.with(mACtivity)
.load(video2.getPic())
.into(holder.restaurantImageView);
holder.restaurantImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// handle click event here
System.out.println("PIC"+video2.getPic());
}
});
}
#Override
public int getItemCount() {
if (mData == null)
return 0;
return mData.size();
}
public class VideoHolder extends RecyclerView.ViewHolder {
ImageView restaurantImageView;
TextView restaurantNameTextView;
TextView restaurantAddressTextView;
TextView restaurantRatingTextView;
TextView costTextView;
TextView distanceTextView;
LinearLayout linearlayout;
public VideoHolder(View itemView) {
super(itemView);
linearlayout=(LinearLayout) itemView.findViewById((R.id.linearlayout));
restaurantImageView = (ImageView) itemView.findViewById(R.id.imageview_restaurant);
restaurantNameTextView = (TextView) itemView.findViewById(R.id.textview_restaurant_name);
restaurantAddressTextView = (TextView) itemView.findViewById(R.id.restaurant_address_textview);
distanceTextView = (TextView) itemView.findViewById(R.id.restaurant_distance_textview);
/* costTextView = (TextView) itemView.findViewById(R.id.cost_for_two_textview);
restaurantRatingTextView = (TextView) itemView.findViewById(R.id.rating);*/
}
public void setTitolo(String titolo) {
restaurantNameTextView.setText(titolo);
}
public void setSottoTitolo(String sottotitolo) {
restaurantAddressTextView.setText(sottotitolo);
}
public void setData(String data) {
distanceTextView.setText(data);
}
/* public void setPic(String pic) {
distanceTextView.setText(pic);
}
public void setCost(String cost) {
costTextView.setText(cost);
}
public void setDistance(String distance) {
distanceTextView.setText(distance);
}*/
}
}
Create a listener Interface and let your MainActivity implement it. That way you can call your callback method in your onClick method.
Interface:
public interface OnImageClickListener {
void onImageClick(String imageData);
}
MainActivity:
public class MainActivity implements OnImageClickListener {
#Override
public void onImageClick(String imageData) {
// handle image data
}
//...
}
Your VideoAdapter:
//...
private OnImageClickListener onImageClickListener;
public VideoAdapter(ArrayList<Video> data, ArrayList<Video> data2, Activity activity, OnImageClickListener onImageClickListener) {
this.mData = data;
this.mData2 = data2;
this.mACtivity = activity;
this.onImageClickListener = onImageClickListener;
}
//...
#Override
public void onBindViewHolder(VideoHolder holder, int position) {
//...
holder.restaurantImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onImageClickListener.onImageClick(video2.getPic());
}
});
//...
}
//...
If you want to pass value from onclick to your Parent activity, use onMethodCallback in your MainActivity:
public class MainActivity extends Activity implements AdapterCallback {
private MyAdapter mMyAdapter;
#Override
public void onMethodCallback(String yourValue) {
// get your value here
}
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mMyAdapter = new MyAdapter(this);
}
}
In your Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private AdapterCallback mAdapterCallback;
public MyAdapter(Context context) {
try {
this.mAdapterCallback = ((AdapterCallback) context);
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement AdapterCallback.");
}
}
#Override
public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, final int i) {
// simple example, call interface here
// not complete
viewHolder.itemView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mAdapterCallback.onMethodCallback();
}
});
}
public static interface AdapterCallback {
void onMethodCallback(String yourValue);
}
}
If you are working with kotlin, the solution is much simpler.
Original Answer here
pass the lamda val itemClick: (Int) -> Unit to your adapter.
class MyRecyclerViewAdapter(params , val itemClick: (Int) -> Unit): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
internal inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
...
itemView.setOnClickListener( {itemClick(layoutPosition)} )
}
}
In your Activity use the returned value position
val myAdapter = MyRecyclerViewAdapter(params) { position ->
// do something
}
Write interface in your adapter like bellow :
interface clickItemListener {
void onItemClick(String order);
}
And your constructor should be :
privat clickItemListener clickItemListeners;
public VideoAdapter(ArrayList<Video> data, ArrayList<Video> data2, Activity activity, clickItemListener clickItemListeners) {
this.mData = data;
this.mData2 = data2;
this.mACtivity = activity;
this.clickItemListeners = clickItemListeners;
}
Then you can pass to Activity :
yourLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
clickItemListeners.onItemClick(yourValue);
}
});
And implement your interface in your activity like bellow :
public class yourActivity extends AppCompatActivity implements
YourAdapter.clickItemListener{
#Override
public void onItemClick(String order) {
//You can get your value here
}
}
Remember that you should pass activity to adapter like bellow :
YourAdapter adapter = new YourAdapter (... , ... , ... , activity.this);

Can't use SharedPreferences variable outside of the MainActivity class

I'm writing a simple app which requires me to remember all checkbox states which are dynamically generated.
I'm trying to use SharedPreferences to save the states of these, I'm using an recyclerview, so I've defined my sharedpreferences and all in the mainactivity which extends Activity.
All good and well, now I'm trying to use this in my Adapter class by trying referencing MainActivity.data, without luck.
MainActivity relevant code:
public class MainActivity extends Activity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
public static String FILENAME = "AnimeConfig";
public SharedPreferences data = getSharedPreferences(FILENAME, 0);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new GetAnime().execute();
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
}
private class GetAnime extends AsyncTask<Void, Void, Void> {
private String animeUrl = "http://www.animeseason.com/anime-list";
public List<String> animes = new ArrayList<String>();
#Override
protected Void doInBackground(Void... params) {
try {
Document document = Jsoup.connect(animeUrl).get();
Elements elements = document.select("div.series_alpha span");
for (Element element : elements) {
animes.add(element.previousElementSibling().text());
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
mAdapter = new MyAdapter(animes);
mRecyclerView.setAdapter(mAdapter);
}
}
MyAdapter relevant code:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<String> mDataset;
public static class ViewHolder extends RecyclerView.ViewHolder {
public CheckBox mCheckbox;
public ViewHolder(CheckBox v) {
super(v);
mCheckbox = v;
}
}
public MyAdapter(List<String> animes) {
mDataset = animes;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
CheckBox v = (CheckBox) LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item, viewGroup, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mCheckbox.setText(mDataset.get(position));
holder.mCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
String animeName = buttonView.getText().toString();
SharedPreferences.Editor editor = MainActivity.data.edit();
}
}
});
}
#Override
public int getItemCount() {
return mDataset.size();
}
}
I don't understand why I can't use MainActivity.data.
you should declare SharedPreferences data as static so you can access it from other classes .
but i prefer to use helper class to do all this work for me
something like this :
public class GeneralHelper {
public static SharedPreferences getSharedPrefrence(Context contextversion) {
//do the code for getting SharedPreferences
}
}

Categories