I'm on a project that, i'm getting datas from Json output. And showing them in my app. Json output includes categories in categories. I'm showing categories with listView, therefore i'm using adapters. It's all ok with FirstPageAdapter but when I switch the other, I can't get datas from FirstPageAdapter with using intent. That question(How to call getIntent() in adapter class) didn't helped me well btw.
FirstPageAdapter.java:
public class FirstPageAdapter extends BaseAdapter {
List<ResponseDTO> responseDTOList;
Context context;
Activity activity;
public FirstPageAdapter(List<ResponseDTO> responseDTOList, Context context, Activity activity) {
this.responseDTOList = responseDTOList;
this.context = context;
this.activity = activity;
}
#Override
public int getCount() {
return responseDTOList.size();
}
#Override
public Object getItem(int i) {
return responseDTOList.get(i);
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = LayoutInflater.from(context).inflate(R.layout.layout_main_act, viewGroup, false);
TextView id, idCategory, parent_id, categoryName, filters, brands;
Button categoriesButton, specsButton;
id = view.findViewById(R.id.id);
idCategory = view.findViewById(R.id.idCategory);
parent_id = view.findViewById(R.id.parent_id);
categoryName = view.findViewById(R.id.categoryName);
filters = view.findViewById(R.id.filters);
brands = view.findViewById(R.id.brands);
categoriesButton = view.findViewById(R.id.childCategories);
specsButton = view.findViewById(R.id.specs);
id.setText("ID : "+responseDTOList.get(i).getId());
idCategory.setText("Category ID: "+responseDTOList.get(i).getIdcategory());
parent_id.setText("Parent ID: "+responseDTOList.get(i).getParentId());
categoryName.setText("Category name : "+responseDTOList.get(i).getCategoryName());
filters.setText("Filters : "+responseDTOList.get(i).getFilters());
brands.setText("Brands : "+responseDTOList.get(i).getBrands());
final String post = "" + responseDTOList.get(i).getId();
final String id_category = "" + responseDTOList.get(i).getIdcategory();
categoriesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(activity, ChildCategoriesAdapter.class);
intent.putExtra("post_id",post);
intent.putExtra("id_category",id_category);
activity.startActivity(intent);
}
});
specsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(activity, ChildCategoriesAdapter.class);
intent.putExtra("post_id",post);
intent.putExtra("id_category",id_category);
activity.startActivity(intent);
}
});
return view;
}
}
ChildCategoriesAdapter.java:
public class ChildCategoriesAdapter extends BaseAdapter {
List<ResponseDTO> responseDTOList;
Context context;
Activity activity;
public ChildCategoriesAdapter(List<ResponseDTO> responseDTOList, Context context, Activity activity) {
this.responseDTOList = responseDTOList;
this.context = context;
this.activity = activity;
}
#Override
public int getCount() {
return responseDTOList.size();
}
#Override
public Object getItem(int i) {
return responseDTOList.get(i);
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
defVars(view, viewGroup);
return null;
}
public void defVars(View view, ViewGroup viewGroup)
{
view = LayoutInflater.from(context).inflate(R.layout.layout_activity_child, viewGroup, false);
Button variationsButton;
TextView id, idCategory, parent_id, categoryName, filters, brands;
id = view.findViewById(R.id.id);
idCategory = view.findViewById(R.id.idCategory);
parent_id = view.findViewById(R.id.parent_id);
categoryName = view.findViewById(R.id.categoryName);
filters = view.findViewById(R.id.filters);
brands = view.findViewById(R.id.brands);
variationsButton = view.findViewById(R.id.variationsButton);
}
public void request()
{
responseDTOList = new ArrayList<>();
//Call<List<ResponseDTO>> call = ManagerAll
}
}
I have their Activities apart from these.
MainActivity.java(FirstPageAdapter):
public class MainActivity extends AppCompatActivity {
FirstPageAdapter adp;
List<ResponseDTO> list;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
defVars();
request();
}
public void defVars()
{
listView = findViewById(R.id.listView);
}
public void request()
{
list = new ArrayList<>();
Call<List<ResponseDTO>> call = ManagerAll.getInstance().bringCall();
call.enqueue(new Callback<List<ResponseDTO>>() {
#Override
public void onResponse(Call<List<ResponseDTO>> call, Response<List<ResponseDTO>> response) {
if (response.isSuccessful())
{
list = response.body();
adp = new FirstPageAdapter(list, getApplicationContext(), MainActivity.this);
listView.setAdapter(adp);
}
}
#Override
public void onFailure(Call<List<ResponseDTO>> call, Throwable t) {
}
});
}
}
Nothing important in ChildCategories.java
Related
Hi, I faced an issue here.. I was creating a chatbot in which user can type a text to send it and also can select a text out of the recommended texts
so I created two RecycleViews
My goal is - when the user selects one of the recommended text, then that text should appear in the Chatting RecycleView
here is my main Activity Class
public class Charts extends AppCompatActivity {
private static final String USER_KEY = "user";
private static final String BOT_KEY = "bot";
RecyclerView chart_recycle,auto_texts;
EditText message_text;
ImageView send_btn,mic_button;
ImageView setting_button;
ChartsAdapter chartsAdapter;
RecyclerView.LayoutManager linearLayout;
ArrayList<ChartModeClass> modeClassesArrayList = new ArrayList<>();
AutoAdapter autoAdapter;
RecyclerView.LayoutManager horizontal;
List<Texts> list = new ArrayList();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatting_hole);
message_text = findViewById(R.id.message_text);
send_btn = findViewById(R.id.send_btn);
mic_button = findViewById(R.id.mic_btn);
setting_button = findViewById(R.id.setting_button);
chart_recycle = findViewById(R.id.chart_recycle);
chart_recycle.setHasFixedSize(true);
auto_texts = findViewById(R.id.auto_texts);
auto_texts.setHasFixedSize(true);
linearLayout = new LinearLayoutManager(getApplicationContext(), RecyclerView.VERTICAL, false);
chart_recycle.setLayoutManager(linearLayout);
//Auto text
horizontal = new LinearLayoutManager(getApplicationContext(),RecyclerView.HORIZONTAL, false);
auto_texts.setLayoutManager(horizontal);
chartsAdapter = new ChartsAdapter(modeClassesArrayList, Charts.this);
chart_recycle.setAdapter(chartsAdapter);
//Auto texts
autoAdapter = new AutoAdapter(getApplicationContext(),list);
auto_texts.setAdapter(autoAdapter);
addInputs();
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(Charts.this);
mic_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bottomSheetDialog.setContentView(R.layout.record);
bottomSheetDialog.show();
}
});
message_text.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().length()==0){
mic_button.setVisibility(View.VISIBLE);
send_btn.setVisibility(View.GONE);
}else {
send_btn.setVisibility(View.VISIBLE);
mic_button.setVisibility(View.GONE);
}
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().isEmpty()){
// Toast.makeText(getApplicationContext(),"Enter text",Toast.LENGTH_LONG).show();
mic_button.setVisibility(View.VISIBLE);
send_btn.setVisibility(View.GONE);
}else {
send_btn.setVisibility(View.VISIBLE);
mic_button.setVisibility(View.GONE);
}
}
#Override
public void afterTextChanged(Editable editable) {
if (editable.toString().length()==0){
mic_button.setVisibility(View.VISIBLE);
send_btn.setVisibility(View.GONE);
}
}
});
send_btn.setOnClickListener(view -> {
if (message_text.getText().toString().isEmpty()) {
Toast.makeText(Charts.this, "Please enter text..", Toast.LENGTH_SHORT).show();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
returnResponse(message_text.getText().toString());
}
message_text.setText("");
});
}
#SuppressLint("NotifyDataSetChanged")
private void returnResponse(String message) {
modeClassesArrayList.add(new ChartModeClass(message, USER_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size()-1);
String url = "http://xxxxxxxxxxxxxxxx"+message;
String BASE_URL = "https://xxxxxxxxx";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Call<MessageModeClass> call = retrofitApi.getMessage(url);
call.enqueue(new Callback<MessageModeClass>() {
#Override
public void onResponse(#NonNull Call<MessageModeClass> call, #NonNull Response<MessageModeClass> response) {
if (response.isSuccessful()) {
MessageModeClass messageModeClass = response.body();
if (messageModeClass != null) {
modeClassesArrayList.add(new ChartModeClass(messageModeClass.getCnt(), BOT_KEY));
}
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
} else {
Toast.makeText(Charts.this, "response is null", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(#NonNull Call<MessageModeClass> call, #NonNull Throwable t) {
modeClassesArrayList.add(new ChartModeClass("No response check your network connection!", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}
});
}
#SuppressLint("NotifyDataSetChanged")
#Override
protected void onStart() {
super.onStart();
String lang = getIntent().getExtras().getString("lang");
if (lang.equals("english")){
modeClassesArrayList.add(new ChartModeClass("Hey welcome back am fema bot", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}else if (lang.equals("swahili")){
modeClassesArrayList.add(new ChartModeClass("Habari karibu miminni bot niliyetengenezw", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}else {
modeClassesArrayList.add(new ChartModeClass("Hey welcome back am fema bot", BOT_KEY));
chartsAdapter.notifyDataSetChanged();
chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
}
}
private void addInputs() {
Texts text1 = new Texts("gender?");
Texts text2 = new Texts("gender equality");
Texts text3 = new Texts("what is good about females");
Texts text4 = new Texts("un goals");
Texts text5 = new Texts("about men");
list.addAll(Arrays.asList(new Texts[]{text1,text2,text3,text4,text5}));
}
}
here is my Adapter class class codes
public class AutoAdapter extends RecyclerView.Adapter<AutoAdapter.ViewHolderClass> {
Context context;
List<Texts> list;
public AutoAdapter(Context context, List<Texts> list) {
this.context = context;
this.list = list;
}
#NonNull
#Override
public ViewHolderClass onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_list,parent,false);
ViewHolderClass viewHolderClass = new ViewHolderClass(view);
return viewHolderClass;
}
#Override
public void onBindViewHolder(#NonNull ViewHolderClass holder, #SuppressLint("RecyclerView") int position) {
holder.input_text.setText(list.get(position).getText());
holder.input_text.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// my stack
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public class ViewHolderClass extends RecyclerView.ViewHolder {
TextView input_text;
public ViewHolderClass(#NonNull View itemView) {
super(itemView);
input_text = itemView.findViewById(R.id.input_text);
}
}
}
You can add a list of your recommendations in another RecyclerView
Then in the ViewHolder of each item of the RecyclerView add Callback to listen on click events when a user clicks one of the item like the following
public class ViewHolderClass extends RecyclerView.ViewHolder {
private TextView input_text;
private final Callback callback; // custom callback
public ViewHolderClass(#NonNull View itemView, Callback callback) {
super(itemView);
this.callback = callback;
input_text = itemView.findViewById(R.id.input_text);
// now add onClickListener of the itemView to fire custom callback
itemView.setOnClickListener(view -> {
this.callback.onItemClick(getAdapterPosition());
});
}
// this is my custom callback for return click event
public interface Callback {
void onItemClick(int position);
}
}
Now inside your adapter add the callback from viewholder
public class AutoAdapter extends RecyclerView.Adapter<AutoAdapter.ViewHolderClass> {
private Context context;
private List<Texts> list;
private AutoAdapterCallback callback;
public AutoAdapter(Context context, List<Texts> list) {
this.context = context;
this.list = list;
}
public setCallback(AutoAdapterCallback callback) {
this.callback = callback;
}
#NonNull
#Override
public ViewHolderClass onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_list,parent,false);
ViewHolderClass viewHolderClass = new ViewHolderClass(view, new ViewHolderClass.Callback() {
#Override
public void onItemClick(int position) {
// forward callback to adapter callback
if (callback != null) {
// get actual item from its position
final Texts texts = getItemByPosition(position);
// send to adapter callback
callback.onItemClick(texts);
}
});
return viewHolderClass;
}
#Override
public void onBindViewHolder(#NonNull ViewHolderClass holder, #SuppressLint("RecyclerView") int position) {
holder.input_text.setText(list.get(position).getText());
// I haven't used this inteady I added callback on viewholder side
// holder.input_text.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View view) {
// // my stack
// }
// });
}
#Override
public int getItemCount() {
return list.size();
}
// return Texts object by given position
public Texts getItemByPosition(int position) {
return this.list.get(position);
}
// add adapter callback to be called by viewholder
public interface AdapterCallback {
void onItemClick(Texts texts);
}
}
After that, now on your Activity you can easily listen on any item when a user clicks and get its corresponding Texts object from list as following:
//code ...
// here
//Auto texts
autoAdapter = new AutoAdapter(getApplicationContext(),list);
//set callback to listen for click events
autoAdapter.setCallback(new AutoAdapter.AutoAdapterCallback() {
#Override
public void onItemClick(Texts texts) {
// you can get your clicked item here
// now you can put texts object to another RecyclerView :)
}
});
auto_texts.setAdapter(autoAdapter);
//code ...
i want create a fragment and have inside a recycler view for show products ...
but when i render it is show this error : RecyclerView: No adapter attached; skipping layout
below i copy my codes;
this code is for adapter class :
private ArrayList<Products> ProductsList;
private Context context;
public Adapter(ArrayList<Products> productsList, Context context) {
ProductsList = productsList;
this.context = context;
}
#Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.row_layout, parent, false);
return new MyHolder(v);
}
#Override
public void onBindViewHolder(MyHolder holder, final int position) {
Products products = ProductsList.get(position);
holder.txtName.setText(products.getName());
holder.txtPrice.setText("$ " + products.getPrice());
Picasso.get().load(Config.ipValue + "/images/" + products.getPhoto()).into(holder.imgV);
holder.imgV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.startAnimation(AnimationUtils.loadAnimation(context, android
.R.anim.slide_in_left));
}
});
}
#Override
public int getItemCount() {
return ProductsList.size();
}
class MyHolder extends RecyclerView.ViewHolder {
TextView txtName;
TextView txtPrice;
ImageView imgV;
public MyHolder(View itemView) {
super(itemView);
txtName = itemView.findViewById(R.id.rowTxtProductName);
txtPrice = itemView.findViewById(R.id.rowTxtPrice);
imgV = itemView.findViewById(R.id.rowImgProduct);
}
}
and this one for web api class :
public class WebApiHandler {
Context context;
String apiLink = "";
ArrayList<Products> products = new ArrayList<>();
public WebApiHandler(Context context) {
this.context = context;
}
void apiConnect(String type) {
switch (type) {
case "getproducts": {
apiLink = Config.getProductsWebApi;
break;
}
}
ProgressDialog dialog = ProgressDialog.show(context, "Connecting...",
"please wait", false, false);
StringRequest request = new StringRequest(Request.Method.POST,
apiLink, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
dialog.dismiss();
showJson(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
dialog.dismiss();
}
});
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(request);
}
private void showJson(String response) {
products.clear();
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("response");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String id = object.getString("id");
String name = object.getString("name");
String description = object.getString("description");
String price = object.getString("price");
String photo = object.getString("photo");
Products p = new Products(id, name, description, price, photo);
products.add(p);
}
} catch (JSONException e) {
e.printStackTrace();
}
VerticalFragment.productsArrayList = products;
IData iData = (IData) context;
iData.sendData();
}}
and my fragment code :
public class VerticalFragment extends Fragment implements IData {
RecyclerView rcVertical;
WebApiHandler webApiHandler;
static ArrayList<Products> productsArrayList = new ArrayList<>();
public VerticalFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_vertical, container, false);
rcVertical = view.findViewById(R.id.rcVertical);
webApiHandler = new WebApiHandler(getContext());
webApiHandler.apiConnect("getproducts");
rcVertical.addOnItemTouchListener(new RecyclerTouchListener(getContext(), rcVertical,
new RecyclerTouchListener.ClickListener() {
#Override
public void onClick(View view, int position) {
ProductActivity.products = productsArrayList.get(position);
startActivity(new Intent(getContext(), ProductActivity.class));
}
#Override
public void onLongClick(View view, int position) {
}
}));
return view;
}
#Override
public void sendData() {
Adapter adapter = new Adapter(productsArrayList, getContext());
rcVertical.setLayoutManager(new LinearLayoutManager((getContext())));
rcVertical.setItemAnimator(new DefaultItemAnimator());
rcVertical.setAdapter(adapter);
}}
i should say i create a interface and have one method i say it sendData
This is a common error when there is no adapter attached to recyclerview upon showing recyclerview. It will not cause any harm to your app, but you could avoid it by setting empty adapter without data, and later when you get your data, provide it to your adapter and notify it
Edit - Example added
Create setter for your list in adapter. After that, in your fragment make adapter global and in onCreateView make instance of your adapter and attach it to recyclerview
adapter = new Adapter(new ArrayList<>(), getContext());
rcVertical.setAdapter(adapter);
...Initialize recyclerview...
And then in your sendData interface put your loaded values in it
adapter.setData(productsArrayList);
adapter.notifyDataSetChanged();
I am using contextual action bar in my fragment("UnitsFragment.java") to delete and edit items of recyclerview. But when I come back from recyclerview adapter class("UnitsRv.java"). The context seems to be null. I tried returning context from adapter and it worked for function "prepareSelection". However for "onActionItemClicked" under ActionMode.callback, I need to get context so that I can use alertdialog for editing the items.
The "requireContext()" throws this error: Fragment UnitsFragment{e3a36c8 (b4957397-055a-4b1c-8af2-fee89a3e9b35)} not attached to a context.
Here are my codes.
UnitsFragment.java
public class UnitsFragment extends Fragment {
private static final String TAG = "UnitsFragment";
private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
ArrayList<UnitsList> unitsLists = new ArrayList<>();
Activity mcontext = getActivity();
Context dcontext;
ActionMode actionMode;
public static ArrayList<UnitsList> selectionList = new ArrayList<>();
public static boolean isInActionMode = false;
List<String> list = DatabaseClient.getInstance(getContext())
.getUserDatabase()
.getUnitDao().findUnitNameList();
public UnitsFragment() {
}
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.menu_item_action, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_edit:
if (selectionList.size() == 1) {
final EditText editText = new EditText(requireContext());
new AlertDialog.Builder(requireContext())
.setTitle("Rename unit name").setView(editText)
.setPositiveButton("Rename", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
UnitsList unitsList = selectionList.get(0);
unitsList.setUnit_name(editText.getText().toString().trim());
isInActionMode = false;
((UnitsRv) mAdapter).changeDataItem(getCheckedLastPosition(), unitsList);
actionMode.finish();
selectionList.clear();
}
})
.create()
.show();
Toast.makeText(getContext(), "Edit", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
}
case R.id.menu_item_delete:
isInActionMode = false;
((UnitsRv) mAdapter).removeData(selectionList);
Toast.makeText(getContext(), "Delete", Toast.LENGTH_SHORT).show();
actionMode.finish();
selectionList.clear();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
}
};
private int getCheckedLastPosition() {
ArrayList<UnitsList> dataSet = UnitsRv.getDataSet();
for (int i = 0; i < dataSet.size(); i++) {
if (dataSet.get(i).equals(selectionList.get(0))) {
return i;
}
}
return 0;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_units, container, false);
setHasOptionsMenu(true);
dcontext = rootView.getContext();
Log.d(TAG, "onCreateView1: " + dcontext);
recyclerView = rootView.findViewById(R.id.rv_units);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
DividerItemDecoration.HORIZONTAL));
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
DividerItemDecoration.VERTICAL));
layoutManager = new GridLayoutManager(getContext(), 2);
recyclerView.setLayoutManager(layoutManager);
for (String string : list) {
unitsLists.add(new UnitsList(string));
}
Log.d(TAG, "onCreateView: " + getContext());
mAdapter = new UnitsRv(mcontext,unitsLists);
recyclerView.setAdapter(mAdapter);
return rootView;
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, #NonNull MenuInflater inflater) {
inflater.inflate(R.menu.add, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_new:
final View customLayout = getLayoutInflater().inflate(R.layout.add_unit_dialog, null);
final EditText edt_unit_name = customLayout.findViewById(R.id.edt_new_unit_name);
final AlertDialog dialog = new AlertDialog.Builder(getContext())
.setView(customLayout)
.setTitle("Unit name")
.setPositiveButton(android.R.string.ok, null) //Set to null. We override the onclick
.setNegativeButton(android.R.string.cancel, null)
.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialogInterface) {
Button ok_btn = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
Button cancel_btn = dialog.getButton(AlertDialog.BUTTON_NEGATIVE);
ok_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String unit_name = edt_unit_name.getText().toString().trim();
if (!TextUtils.isEmpty(unit_name)) {
String old_unit_name = DatabaseClient.getInstance(getContext())
.getUserDatabase()
.getUnitDao()
.findByUnitName(unit_name);
if (old_unit_name == null) {
DatabaseClient.getInstance(getContext())
.getUserDatabase()
.getUnitDao()
.insertUnits(new UnitsList(unit_name));
unitsLists.add(new UnitsList(unit_name));
dialog.dismiss();
} else {
edt_unit_name.setError("Unit already exists");
}
} else {
edt_unit_name.setError("Can't be empty");
}
}
});
cancel_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog.dismiss();
}
});
}
});
dialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
public void prepareSelection(Context context,int position) {
if(actionMode == null) {
isInActionMode = true;
for (String string : list) {
unitsLists.add(new UnitsList(string));
}
mAdapter = new UnitsRv(context, unitsLists);
Log.d(TAG, "prepareSelection: " + mAdapter);
Log.d(TAG, "prepareSelection1: " + dcontext);
mcontext = (Activity)context;
actionMode = mcontext.startActionMode(actionModeCallback);
mAdapter.notifyDataSetChanged();
if (!selectionList.contains(unitsLists.get(position))) {
selectionList.add(unitsLists.get(position));
}
updateViewCounter();
}
}
private void updateViewCounter() {
int counter = selectionList.size();
if (counter == 1) {
actionMode.setTitle(counter + "item selected");
} else {
actionMode.setTitle(counter + "items selected");
}
}
}
This is my Adapter class.
UnitsRv.java
public class UnitsRv extends RecyclerView.Adapter<UnitsRv.ViewHolder> {
private static final String TAG = "UnitsRv";
private static ArrayList<UnitsList> munitsLists = new ArrayList<>();
UnitsFragment unitsFragment = new UnitsFragment();
Context mcontext;
public UnitsRv(Context context,ArrayList<UnitsList> unitsLists) {
mcontext = context;
munitsLists = unitsLists;
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView unit_name;
public ViewHolder(View v) {
super(v);
unit_name = v.findViewById(R.id.unit_name);
v.setOnLongClickListener(this);
}
#Override
public void onClick(View view) {
if (UnitsFragment.isInActionMode){
unitsFragment.prepareSelection(mcontext,getAdapterPosition());
notifyItemChanged(getAdapterPosition());
}
}
#Override
public boolean onLongClick(View view) {
Log.d(TAG, "onLongClick: " + getAdapterPosition());
unitsFragment.prepareSelection(view.getContext(),getAdapterPosition());
return true;
}
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.units_item, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
holder.unit_name.setText(munitsLists.get(position).getUnit_name());
if (UnitsFragment.isInActionMode){
if (UnitsFragment.selectionList.contains(munitsLists.get(position))){
holder.itemView.setBackgroundResource(R.color.colorSelected);
}
}
}
#Override
public int getItemCount() {
return munitsLists.size();
}
public static ArrayList<UnitsList> getDataSet() {
return munitsLists;
}
public void changeDataItem(int position, UnitsList unitsList) {
munitsLists.set(position, unitsList);
notifyDataSetChanged();
}
public void removeData(ArrayList<UnitsList> list) {
for (UnitsList unitsList : list) {
munitsLists.remove(unitsList);
}
notifyDataSetChanged();
}
}
First, you should not create instance of your UnitsFragment inside your adapter.
You can use EventBus to communicate between Activities, Fragments, Adapters, etc.
Or You can do your task using interface. like below.
Create an interface like this
public interface AdapterCallback {
void prepareSelection(Context context,int position);
}
In your UnitsFragment implement the above interface. like the following
public class UnitsFragment extends Fragment implements AdapterCallback{
// your other codes
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_units, container, false);
setHasOptionsMenu(true);
// .... your other codes
Log.d(TAG, "onCreateView: " + getContext());
// modify below line like this
mAdapter = new UnitsRv(mcontext, unitsLists, this); // here you have to pass an extra parameter that will implement your callback method from adapter.
recyclerView.setAdapter(mAdapter);
return rootView;
}
// ... you other codes
#Override
public void prepareSelection(Context context,int position) {
if(actionMode == null) {
isInActionMode = true;
for (String string : list) {
unitsLists.add(new UnitsList(string));
}
mAdapter = new UnitsRv(context, unitsLists,this); // add this as parameter.
Log.d(TAG, "prepareSelection: " + mAdapter);
Log.d(TAG, "prepareSelection1: " + dcontext);
mcontext = (Activity)context;
actionMode = mcontext.startActionMode(actionModeCallback);
mAdapter.notifyDataSetChanged();
if (!selectionList.contains(unitsLists.get(position))) {
selectionList.add(unitsLists.get(position));
}
updateViewCounter();
}
}
// other codes
}
Now, inside your Adapter you need to add an extra argument in constructor of UnitsRv and call your interface method from adapter ussing mAdapterCallback.
public class UnitsRv extends RecyclerView.Adapter<UnitsRv.ViewHolder> {
private static final String TAG = "UnitsRv";
private static ArrayList<UnitsList> munitsLists = new ArrayList<>();
UnitsFragment unitsFragment = new UnitsFragment(); // remove this line
private AdapterCallback mAdapterCallback; // add this line
Context mcontext;
public UnitsRv(Context context,ArrayList<UnitsList> unitsLists, AdapterCallback callback) {
mcontext = context;
munitsLists = unitsLists;
this.mAdapterCallback = callback; // add this line
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView unit_name;
public ViewHolder(View v) {
super(v);
unit_name = v.findViewById(R.id.unit_name);
v.setOnLongClickListener(this);
}
#Override
public void onClick(View view) {
if (UnitsFragment.isInActionMode){
mAdapterCallback.prepareSelection(mcontext,getAdapterPosition()); // modify this line
notifyItemChanged(getAdapterPosition());
}
}
#Override
public boolean onLongClick(View view) {
Log.d(TAG, "onLongClick: " + getAdapterPosition());
mAdapterCallback.prepareSelection(view.getContext(),getAdapterPosition()); // modify this line
return true;
}
}
// your other codes....
}
You should check for your fragment is attached or not with isAdded()
place if(!isAdded()) return in your onActionItemClicked. and replace requireContext() with getContext() because requireContext() always throws IllegalStateException if fragment is not attached.
override onAttach method to save context in your fragment.
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.context= context;
}
Hope this helps.
I have an Fragment with recycleview where I populate it with json items from internet.
It load fine and Next step I want to is open new Activity when any row is clicked. It works in activity, thus I modified the same code for fragment but for fragment it throws exception in line
mExampleAdapter.setOnItemClickListener(getActivity());
with errror setOnItemClickListener of refrence adatper cannot be applied to Fragment activty and thus when I change line to
(ExampleAdapter.OnItemClickListener)
and when i build and run . Then app crashes with error that Mainactivity which holds framgnet cannot be cast in to .ExampleAdapter$OnItemClickListener
Here is my whole Fragment class
public class Mynotes extends Fragment implements ExampleAdapter.OnItemClickListener{
public static final String YTD_LINK = "link";
private RecyclerView mRecyclerView;
private ExampleAdapter mExampleAdapter;
private ArrayList<ExampleItem> mExampleList;
private RequestQueue mRequestQueue;
String url="https://api.myjson.com/bins/16mecx";
public Mynotes() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.activity_jsonfeed, container, false);
mRecyclerView = view.findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.addItemDecoration(new MyDividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL, 36));
mExampleList = new ArrayList<>();
mExampleAdapter = new ExampleAdapter(getActivity(), mExampleList);
mRecyclerView.setAdapter(mExampleAdapter);
mExampleAdapter.setOnItemClickListener((ExampleAdapter.OnItemClickListener) getActivity());
parseJSON();
return view;
}
private void parseJSON() {
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
myProgressBar.setVisibility(View.GONE);
try {
JSONArray jsonArray = response.getJSONArray("hits");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject hit = jsonArray.getJSONObject(i);
String videoTitle = hit.getString("title");
String link = hit.getString("link");
mExampleList.add(new ExampleItem(videoTitle, link));
mExampleAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mRequestQueue.add(request);
}
#Override
public void onItemClick(int position) {
Intent intent = new Intent(getActivity(), NewActiviyt.class);
ExampleItem clickedItem = mExampleList.get(position);
intent.putExtra(YTD_LINK, clickedItem.getmLink());
startActivity(intent);
}
#Override
public void onRefresh() {
}
}
and my Adapter Class is
public class ExampleAdapter extends RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder> {
private Context mContext;
private ArrayList<ExampleItem> mExampleList;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public ExampleAdapter(Context context, ArrayList<ExampleItem> exampleList) {
mContext = context;
mExampleList = exampleList;
}
#Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.example_item, parent, false);
return new ExampleViewHolder(v);
}
#Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
ExampleItem currentItem = mExampleList.get(position);
String title = currentItem.getTitle();
// int likeCount = currentItem.getLikeCount();
// String imageUrl = currentItem.getImageUrl();
holder.mTextViewCreator.setText(title);
// holder.mTextViewLikes.setText("Likes: " + likeCount);
// Glide.with(mContext).load(imageUrl).apply(RequestOptions.circleCropTransform()).into(holder.mImageView);
}
#Override
public int getItemCount() {
return mExampleList.size();
}
public class ExampleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView mTextViewCreator;
// public TextView mTextViewLikes;
// public ImageView mImageView;
public ExampleViewHolder(View itemView) {
super(itemView);
// mTextViewLikes = itemView.findViewById(R.id.text_view_likes);
// mImageView = itemView.findViewById(R.id.image_view);
mTextViewCreator = itemView.findViewById(R.id.text_title);
}
#Override
public void onClick(View view) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
mListener.onItemClick(position);
}
}
}
}
}
Thanks in advance.
replace getActivity with getContext when you work in fragment,
You can read more here
What is different between getContext and getActivity from Fragment in support library?
Your activity should implement ExampleAdapter.OnItemClickListener
I want to retrieve data from my Database to a recyclerview with multiples layout. How to retrieve contents respectively according to whether it is picture or video?
I mean I don't want to give a position to my getItemView like if image == 1 to do this.
I want to retrieve different types of contents in in their particular layouts.
Ex: Like Facebook, if someone post a video and another person post a text they will be shown while scrolling.
Fragment
public class Discover extends Fragment {
private DatabaseReference mDatabaseRefAll;
private RecyclerView recyclerViewDiscover;
DiscoverRecyclerViewAdapter discoverRecyclerViewAdapter;
private ArrayList<Object> discoverItems = new ArrayList<Object>();
private ArrayList<discoverModell> objects = new ArrayList<>();
public Discover() {
// Required empty public constructor
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_discover, container, false);
recyclerViewDiscover = (RecyclerView) view.findViewById(R.id.rcDiscover);
recyclerViewDiscover.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerViewDiscover.setHasFixedSize(true);
discoverRecyclerViewAdapter = new DiscoverRecyclerViewAdapter(getContext(), discoverItems, objects);
// set adapter
recyclerViewDiscover.setAdapter(discoverRecyclerViewAdapter);
recyclerViewDiscover.setItemAnimator(new DefaultItemAnimator());
return view;
}
private void loadPost() {
// loading the posts
mDatabaseRefAll = FirebaseDatabase.getInstance().getReference("Testing");
Query queryDiscover = mDatabaseRefAll;
queryDiscover.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, String s) {
Post post = dataSnapshot.getValue(Post.class);
discoverItems.add(post);
discoverRecyclerViewAdapter.notifyDataSetChanged();
// recyclerViewDiscover.scrollToPosition( discoverItems.size() - 1);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
The Adapter
public class DiscoverRecyclerViewAdapter extends RecyclerView.Adapter<DiscoverRecyclerViewAdapter.DiscoverViewHolder> {
private Context ctx;
private ArrayList<Object> arrayListDiscoverContent;
private ArrayList<Object> horizontalContent;
private ArrayList<discoverModell> arraydiscoverRow;
private static final int LAYOUT_ADS = 1;
private static int LAYOUT_DISCOVERROW = 0;
private static int LAYOUT_DISCOVERCONTENT = 2;
public DiscoverRecyclerViewAdapter(Context context, ArrayList<Object> arrayListDiscoverContent, ArrayList<discoverModell> arraydiscoverRow) {
this.ctx = context;
this.arrayListDiscoverContent = arrayListDiscoverContent;
this.arraydiscoverRow = arraydiscoverRow;
}
#Override
public DiscoverViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ctx = parent.getContext();
if (viewType == LAYOUT_ADS){
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.ad_banner_view, parent, false);
return new DiscoverViewHolder(view);
}
if (viewType == LAYOUT_DISCOVERROW) {
View goToContent = LayoutInflater.from(parent.getContext()).inflate(R.layout.discover_by_content, parent, false);
return new DiscoverViewHolder(goToContent);
} else if (viewType == LAYOUT_DISCOVERCONTENT) {
View videoView = LayoutInflater.from(parent.getContext()).inflate(R.layout.pmc_video_row, parent, false);
return new DiscoverViewHolder(videoView);
}
return null;
}
#Override
public void onBindViewHolder(DiscoverViewHolder holder, int position) {
//String type = arrayListDiscoverContent.get(position).getType();
if (getItemViewType(position) == LAYOUT_ADS){
DiscoverViewHolder.adsDiscoverView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(ctx, google_ads_video.class);
ctx.startActivity(intent);
}
});
} else if (getItemViewType(position) == LAYOUT_DISCOVERROW) {
final discoverModell discoverM = (discoverModell) arraydiscoverRow.get(position);
DiscoverViewHolder.obooks.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent booksIntent = new Intent(ctx, menu_book.class);
ctx.startActivity(booksIntent);
}
});
DiscoverViewHolder.olisticles.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent listIntent = new Intent(ctx, menu_listicle.class);
ctx.startActivity(listIntent);
}
});
DiscoverViewHolder.oinfo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent odatingIntent = new Intent(ctx, Buildinginfo.class);
ctx.startActivity(odatingIntent);
}
});
}
}
public static class DiscoverViewHolder extends RecyclerView.ViewHolder {
public static View adsDiscoverView, gotobannerview;
public static Context ctx;
public static TextView name_discover, autordiscover;
PublisherAdView mPublisherAdView;
public DiscoverViewHolder(View itemView) {
super(itemView);
this.ctx = ctx;
gotobannerview = itemView;
name_discover = itemView.findViewById(R.id.textView19);
autordiscover = itemView.findViewById(R.id.autorId);
}
}
public static class DiscoverRowViewHolder extends RecyclerView.ViewHolder {
public static Context ctx;
public static View adsDiscoverView;
public static ImageView obooks, olisticles, oinfo;
public DiscoverRowViewHolder(View itemView) {
super(itemView);
this.ctx = ctx;
adsDiscoverView = itemView;
obooks = (ImageView) itemView.findViewById(R.id.obooks);
olisticles = (ImageView) itemView.findViewById(R.id.olisticles);
oinfo = (ImageView) itemView.findViewById(R.id.oinfo);
}
}
#Override
public int getItemCount() {
return arrayListDiscoverContent.size();
}
#Override
public int getItemViewType(int position) {
if (position == 0){
return LAYOUT_DISCOVERROW;
} else if (position == 1){
return LAYOUT_ADS;
}
return LAYOUT_DISCOVERCONTENT;
}