After some research on this one of the complex issue
I did this like this for my currency convertor project:
Below are steps:
Created A Custom Adapter with inner ViewHolder
Created an Interference for Selection changed and to notify the
Adaper in MainActivty
Created an Model Class Created an layout for My list
Coding:
Adapter and View Holder
class Adapter extends RecyclerView.Adapter<Adapter.VH> {
ArrayList<Currency> list, checkedCurrencies = new ArrayList<>();
CurrencySelectionChangelistener listener;
public Adapter(#NonNull ArrayList<Currency> list, CurrencySelectionChangelistener listener) {
this.list = list;
this.listener = listener;
}
#NonNull
#Override
public VH onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new VH(LayoutInflater.from(getContext()).inflate(R.layout.layout_list_of_all_items, parent, false));
}
#Override
public void onBindViewHolder(#NonNull VH holder, #SuppressLint("RecyclerView") int position) {
Currency currentCurrency = list.get(position);
holder.checkBox.setChecked(currentCurrency.isChecked());
holder.mDis.setText(currentCurrency.getDescription());
//ignore below line it's just for sorting the string to set On TextView and with another purpose
String name = currentCurrency.getName().toLowerCase().replace(" ", "");
holder.mName.setText(name.toUpperCase());
holder.mLogo.setImageResource(currentCurrency.getLogo(name));
holder.checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.checkBox.isChecked()) {
list.get(position).setChecked(true);
checkedCurrencies.add(currentCurrency);
} else if (!holder.checkBox.isChecked()) {
list.get(position).setChecked(false);
checkedCurrencies.remove(currentCurrency);
}
//calling the interference's function
onSelection(checkedCurrencies);
}
});
}
#Override
public int getItemCount() {
return list.size();
}
class VH extends RecyclerView.ViewHolder {
TextView mName, mDis;
ImageView mLogo;
CheckBox checkBox;
public VH(#NonNull View itemView) {
super(itemView);
checkBox = itemView.findViewById(R.id.checkboxAllItems);
mLogo = itemView.findViewById(R.id.ImageViewAllItemLogo);
mName = itemView.findViewById(R.id.textViewAllItemCName);
mDis = itemView.findViewById(R.id.textViewAllItemCDis);
}
}
}
Interface
public interface CurrencySelectionChangelistener {
public void onSelection(ArrayList<Currency> currencies);}
Fragment in Which I'm using RecyclerView
public class AddMoreCurrencyFragment extends Fragment implements CurrencySelectionChangelistener {
FragmentAddNewCurrencyBinding binding;
ArrayList<Currency> currencies;
Adapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentAddNewCurrencyBinding.inflate(inflater);
CurrencyContainerActivity.title.setVisibility(View.VISIBLE);
CurrencyContainerActivity.title.setText("Add Currency");
CurrencyContainerActivity.backBtn.setVisibility(View.VISIBLE);
currencies = new ArrayList<>();
for (Currency c : CurrencyContainerActivity.listOfCurrencies) {
currencies.add(new Currency(c.getName(), c.getDescription(), false));
}
adapter = new Adapter(currencies, this);
binding.recView.setAdapter(adapter);
binding.done.setOnClickListener(view -> {
});
return binding.getRoot();
}
#Override
public void onSelection(ArrayList<Currency> currencies) {
CurrencyContainerActivity.listToAdd.addAll(currencies);
Toast.makeText(getContext(), currencies.toString(), Toast.LENGTH_LONG).show();
adapter.notifyDataSetChanged();
}
}
xml layout for each item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#color/white"
android:orientation="vertical"
android:weightSum="3">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="59dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="10dp"
android:weightSum="3">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.89"
app:cardCornerRadius="16dp">
<ImageView
android:id="#+id/ImageViewAllItemLogo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/flag" />
</androidx.cardview.widget.CardView>
<TextView
android:id="#+id/textViewAllItemCName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="19dp"
android:layout_weight=".75"
android:fontFamily="#font/poppins"
android:text="#string/pkr"
android:textAlignment="center"
android:textAllCaps="true"
android:textColor="#color/black"
android:textSize="16sp" />
<TextView
android:id="#+id/textViewAllItemCDis"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_weight="0.47"
android:fontFamily="#font/poppins"
android:text="#string/pkr"
android:textAlignment="textStart"
android:textColor="#color/black"
android:textSize="13sp" />
<CheckBox
android:id="#+id/checkboxAllItems"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_weight="0.90"
android:background="#drawable/radio_selector"
android:button="#android:color/transparent" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#3F000000" />
</LinearLayout>
Model Class
public class Currency {
private String Name, Description;
private int logo;
boolean isChecked;
public Currency(String name, String description, boolean isChecked) {
Name = name;
Description = description;
this.isChecked = isChecked;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getDescription() {
return Description;
}
public void setDescription(String description) {
Description = description;
}
}
if anything i missed can for that. Thanks
Related
I am developing an app in which I am showing users data in a recyclerview. I have used a library which shows preview of a url.
My Problem
Each user has video1, video2, and video3 nodes and I want to display the data of each user 3 times i.e. in the first itemView I want to display video1, in the 2nd video2, and in the 3rd video3. So each user will have 3 itemViews. Below is my code. Please do ask if you need any clarification. Thanks in advance
[![Database Struction][1]][1]
[1]: https://i.stack.imgur.com/XJQqt.png
Adapter Class
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
Context context;
ArrayList<ModelClass> modelClass = new ArrayList<>();
public MyAdapter(Context context, ArrayList<ModelClass> modelClass) {
this.context = context;
this.modelClass = modelClass;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.gig_display_layout, parent, false));
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.urlEmbeddedView.setURL(modelClass.get(position).getVideo1(), new URLEmbeddedView.OnLoadURLListener() {
#Override
public void onLoadURLCompleted(URLEmbeddedData data) {
holder.urlEmbeddedView.title(data.getTitle());
holder.urlEmbeddedView.description(data.getDescription());
holder.urlEmbeddedView.host(data.getHost());
holder.urlEmbeddedView.thumbnail(data.getThumbnailURL());
holder.urlEmbeddedView.favor(data.getFavorURL());
}
});
}
#Override
public int getItemCount() {
return modelClass.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
URLEmbeddedView urlEmbeddedView;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
urlEmbeddedView = itemView.findViewById(R.id.urlView);
}
}
}
Model Class
public class ModelClass {
public String name, video1, video2, video3, videos;
int showVideoCount = 1;
int lifeTimeClicks = 0;
int lifeTimeClicksOnProfile = 0;
int dailyClicksOnProfile = 0;
int dailyClicksByYou = 0;
public ModelClass(String name, String video1, String video2, String video3) {
this.name = name;
this.video1 = video1;
this.video2 = video2;
this.video3 = video3;
}
public ModelClass() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVideo1() {
return video1;
}
public void setVideo1(String video1) {
this.video1 = video1;
}
public String getVideo2() {
return video2;
}
public void setVideo2(String video2) {
this.video2 = video2;
}
public String getVideo3() {
return video3;
}
public void setVideo3(String video3) {
this.video3 = video3;
}
HomeFragment
dRef.addListenerForSingleValueEvent(new ValueEventListener() { // singleValueEvent will only call the firebase database once
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
list = new ArrayList<ModelClass>();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
ModelClass modelClass = dataSnapshot.getValue(ModelClass.class);
list.add(modelClass);
Collections.shuffle(list); // This will shuffle the links
}
MyAdapter adapter = new MyAdapter(getActivity(), list);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
Sir Use Nested Recyclerview, Inside your main Item view in xml use another recyclerview.
e.g:
MainAcitivty.xml
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.constraint.ConstraintLayout>
FirstItem.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#f3f3f3"
app:cardElevation="8dp"
android:layout_margin="12dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:orientation="vertical">
<TextView
android:id="#+id/tv_item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12sp"
android:textSize="18sp"
android:text="Item Title"/>
//recycler for video
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_sub_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
SubItem.xml (for displaying videos) :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tv_sub_item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="Sub item title"/> //Video
</RelativeLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
you have model and adapter for MainItem already, Now create model and adapter for subitem(for videos), now in onBindViewHolder of the MainItemAdapter, set subItem layout, also initialize in ItemViewHolder in MainItemAdapter.
e.g. something like this
#Override
public void onBindViewHolder(#NonNull ItemViewHolder itemViewHolder, int i) {
LinearLayoutManager layoutManager = new LinearLayoutManager(
itemViewHolder.rvSubItem.getContext(),
LinearLayoutManager.VERTICAL,
false
);
// Create sub item view adapter
SubItemAdapter subItemAdapter = new SubItemAdapter(item.getSubItemList());
itemViewHolder.rvSubItem.setLayoutManager(layoutManager);
itemViewHolder.rvSubItem.setAdapter(subItemAdapter);
itemViewHolder.rvSubItem.setRecycledViewPool(viewPool);
}
class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView tvItemTitle;
private RecyclerView rvSubItem;
ItemViewHolder(View itemView) {
super(itemView);
tvItemTitle = itemView.findViewById(R.id.tv_item_title);
rvSubItem = itemView.findViewById(R.id.rv_sub_item);
}
}
I'm writing a shopping list app that will save data to a Firebase Realtime database and update the screen in real time. As of right now I have it so that when you click the "+ List item" button, it adds a ShoppingListItem to the database with the name "test". It does that correctly, but it isn't updating the screen. I've double checked that the methods are being called, but the screen isn't reflecting the updated data. I have also tried using notifyDataSetChanged() and that hasn't seemed to help either.
This is the code for the ShoppingListFragment:
public class ShoppingListFragment extends Fragment {
private ArrayList<String> listItems = new ArrayList<String>();
private ListView mListView;
private TextView addItemButton;
private LinearLayout ll;
private RecyclerView rv;
private FirebaseRecyclerAdapter<ShoppingListItem, ShoppingListHolder> firebaseRecyclerAdapter;
private DatabaseReference mDatabase;
public ShoppingListFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
mDatabase = FirebaseDatabase.getInstance().getReference();
//get reference to user
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
Query query = mDatabase.child("users").child(uid).child("shopping");
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_shopping_list, container, false);
rv = view.findViewById(R.id.shopping_list);
rv.setLayoutManager(new LinearLayoutManager(getContext()));
// find the + List Item button
final TextView addCheckBox = view.findViewById(R.id.add_check_box);
addCheckBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addNewCheckBox(container);
}
});
FirebaseRecyclerOptions<ShoppingListItem> options = new FirebaseRecyclerOptions.Builder<ShoppingListItem>()
.setQuery(query, ShoppingListItem.class)
.build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ShoppingListItem, ShoppingListHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull ShoppingListHolder holder, int position, #NonNull ShoppingListItem item) {
holder.setItem(item);
}
#NonNull
#Override
public ShoppingListHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.shopping_list_item, parent, false);
return new ShoppingListHolder(view);
}
};
return view;
}
#Override
public void onStart() {
super.onStart();
firebaseRecyclerAdapter.startListening();
rv.setAdapter(firebaseRecyclerAdapter);
}
#Override
public void onStop() {
super.onStop();
if (firebaseRecyclerAdapter != null) {
firebaseRecyclerAdapter.stopListening();
}
}
public void addNewCheckBox(ViewGroup container) {
String key = mDatabase.child("users").child(getUid()).child("shopping_list").push().getKey();
ShoppingListItem item = new ShoppingListItem("test");
mDatabase.child("users").child(getUid()).child("shopping_list").child(key).setValue(item);
firebaseRecyclerAdapter.notifyDataSetChanged();
}
public int convertToPx(int input) {
DisplayMetrics metrics = getResources().getDisplayMetrics();
int px = (int) (input * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
private class ShoppingListHolder extends RecyclerView.ViewHolder {
private final EditText itemName;
public ShoppingListHolder(View itemView) {
super(itemView);
itemName = itemView.findViewById(R.id.item_name);
}
public void setItem(ShoppingListItem item) {
itemName.setText(item.getItemName());
}
}
private String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
}
and the ShoppingListItem:
public class ShoppingListItem {
private String itemName;
private String type;
private String unit;
private int quantity;
private String location;
public ShoppingListItem() {
}
public ShoppingListItem(String name) {
this.itemName = name;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
}
XML for the shopping list view:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/home_fragment_main_layout"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.jggdevelopment.wannacook.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Shopping List"
android:textStyle="bold"
android:textSize="18sp"
android:layout_marginStart="16dp"
android:layout_marginBottom="16dp"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/shopping_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:clipToPadding="false"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/add_check_box"
android:text="+ List item"
android:textSize="16sp"
android:layout_marginStart="40dp"
android:layout_marginTop="16dp"/>
</LinearLayout>
and XML for each line item in the shopping list:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/item_name"
android:layout_weight="1"
android:layout_marginStart="12dp"
android:layout_marginEnd="32dp"
android:inputType="text"
android:background="#android:color/transparent"
/>
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:id="#+id/xbutton"
android:layout_marginEnd="12dp"
android:src="#drawable/ic_close_white_24dp"
android:layout_gravity="center_vertical"/>
</LinearLayout>
This is not working because you forgot to set the adapter in the onCreate() method. To solve this, add rv.setAdapter(firebaseRecyclerAdapter);, right before you are returning the view like this:
rv.setAdapter(firebaseRecyclerAdapter);
return view;
And you can remove that line of code from the onStart() method because is not needed there.
If you are interested, I have created a tutorial in which I'm explaining step by step, how to build a Shopping List App using Cloud Firestore and Android.
I am trying to implement a RecyclerView with two different layouts. In the MainActivity I first create ListItem object and add it to the list and then add that to the adapter, but it doesn't show. And also I am calling a method that creates ListItem object and adds it to the list and then notifies the adapter, but it still doesn't show. Here is my code so far:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="nl.iansoft.www.recyclerviewproblem.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/rvList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="100dp"
/>
</android.support.constraint.ConstraintLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ArrayList<ListItem> listItems;
private CustomAdapter customAdapter;
private RecyclerView rvList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rvList = (RecyclerView)findViewById(R.id.rvList);
listItems = new ArrayList<>();
ListItem listItem = new ListItem("MyName", "MyLatsName", "MyEmail");
listItems.add(listItem);
customAdapter = new CustomAdapter(listItems);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
rvList.setLayoutManager(mLayoutManager);
rvList.setItemAnimator(new DefaultItemAnimator());
rvList.setAdapter(customAdapter);
addItemToTheList();
}
private void addItemToTheList(){
ListItem listItem = new ListItem("MyName", "MyLatsName", "MyEmail");
listItems.add(listItem);
customAdapter.notifyDataSetChanged();
}
}
CustomAdapter.java
public class CustomAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<ListItem> listItems;
public class ListItem1ViewHolder extends RecyclerView.ViewHolder {
public TextView tvName;
public TextView tvLastName;
public TextView tvEmail;
public ListItem1ViewHolder(View view) {
super(view);
tvName = (TextView) view.findViewById(R.id.tvName);
tvLastName = (TextView) view.findViewById(R.id.tvLastName);
tvEmail = (TextView) view.findViewById(R.id.tvEmail);
}
}
public class ListItem2ViewHolder extends RecyclerView.ViewHolder {
public TextView tvName2;
public TextView tvLastName2;
public TextView tvEmail2;
public ListItem2ViewHolder(View view) {
super(view);
tvName2 = (TextView) view.findViewById(R.id.tvName2);
tvLastName2 = (TextView) view.findViewById(R.id.tvLastName2);
tvEmail2 = (TextView) view.findViewById(R.id.tvEmail2);
}
}
public CustomAdapter(ArrayList<ListItem> listItems) {
this.listItems = listItems;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
if(viewType == 1){
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_list_item, parent, false);
return new CustomAdapter.ListItem1ViewHolder(itemView);
}else{
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_list_item2, parent, false);
return new CustomAdapter.ListItem2ViewHolder(itemView);
}
}
#Override
public int getItemViewType(int position) {
if(listItems.get(position).getName().equals("MyName")){
return 1;
}else{
return 2;
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ListItem listItem = listItems.get(position);
if(holder.getItemViewType() == 1) {
ListItem1ViewHolder listItem1ViewHolder = (ListItem1ViewHolder) holder;
listItem1ViewHolder.tvName.setText(listItem.getName());
listItem1ViewHolder.tvLastName.setText(listItem.getLastName());
listItem1ViewHolder.tvEmail.setText(listItem.getEmail());
}else{
ListItem2ViewHolder listItem2ViewHolder = (ListItem2ViewHolder)holder;
listItem2ViewHolder.tvName2.setText(listItem.getName());
listItem2ViewHolder.tvLastName2.setText(listItem.getLastName());
listItem2ViewHolder.tvEmail2.setText(listItem.getEmail());
}
}
#Override
public int getItemCount() {
return listItems.size();
}
}
ListItem.java
public class ListItem {
private String name;
private String lastName;
private String email;
public ListItem() {
}
public ListItem(String name, String lastName, String email) {
this.name = name;
this.lastName = lastName;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
my_list_item2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvName2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="Name2"
android:layout_marginTop="15dp"
android:padding="5dp"/>
<TextView
android:id="#+id/tvLastName2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="Last Name2"
android:layout_below="#+id/tvName2"
android:layout_marginTop="10dp"
android:padding="5dp" />
<TextView
android:id="#+id/tvEmail2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="my#email.com"
android:layout_below="#+id/tvLastName2"
android:layout_marginTop="5dp"
android:padding="5dp" />
</RelativeLayout>
my_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="Name"
android:layout_marginTop="15dp"
android:padding="5dp"/>
<TextView
android:id="#+id/tvLastName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="Last Name"
android:layout_below="#+id/tvName"
android:layout_marginTop="10dp"
android:padding="5dp" />
<TextView
android:id="#+id/tvEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="my#email.com"
android:layout_below="#+id/tvLastName"
android:layout_marginTop="5dp"
android:padding="5dp" />
</RelativeLayout>
The issue is in ConstraintLayout. Because you haven't specified any constraints to your RecyclerView.
Either specify constraints, or move to another layout (e.g. FrameLayout).
But specifically in this case you do not need parent layout, because it is useless, as long as you have only RecyclerView in your view hierarchy.
i want to be able to do this to the code i have already I am new to programing please help.
- Add an icon the user can click (per item) to remove it
- When clicked that item on the list should be removed
-The item should be removed from storage as well (so it doesn't appear next time they load up the app)
here is my code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String Log_TAG = "ToDoApp";
private ToDoListManager listManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView todoList = (ListView) findViewById(R.id.todo_list);
listManager = new ToDoListManager(getApplicationContext());
ToDoItemAdapter adapter = new ToDoItemAdapter(
this,
listManager.getList()
);
ImageButton addButton = (ImageButton) findViewById(R.id.add_item);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onAddButtonClick();
}
});
}
#Override
protected void onPause() {
super.onPause();
listManager.saveList();
}
private void onAddButtonClick() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.add_item);
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
builder.setPositiveButton(
R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ToDoItem item = new ToDoItem(
input.getText().toString(),
false
);
listManager.addItem(item);
}
});
builder.setNegativeButton(
R.string.cancel,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
private class ToDoItemAdapter extends ArrayAdapter<ToDoItem> {
private Context context;
private List<ToDoItem> items;
public ToDoItemAdapter(
Context context,
List<ToDoItem> items
) {
super(context, -1, items);
this.context = context;
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.to_do_item_layout, parent, false);
}
TextView textView = (TextView) convertView.findViewById(R.id.item);
CheckBox CheckBox = (CheckBox) convertView.findViewById(R.id.CheckBox);
textView.setText(items.get(position).getDescription());
CheckBox.setChecked(items.get(position).isComplete());
convertView.setTag(items.get(position));
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ToDoItem item = (ToDoItem) v.getTag();
item.toggleComplete();
notifyDataSetChanged();
}
});
return convertView;
}
}
}
todolistmanager.java
public class ToDoListManager {
private static final String APP_PREFERENCES = "todoapp";
private static final String TODO_ITEMS = "itemslist";
private List<ToDoItem> items;
private SharedPreferences savedData;
public ToDoListManager(Context context) {
savedData = context.getSharedPreferences (
APP_PREFERENCES,
Context.MODE_PRIVATE
);
String json = savedData.getString(TODO_ITEMS, null);
if(json == null) {
items = new ArrayList<>();
} else {
Type type = new TypeToken<List<ToDoItem>>() {}.getType();
items = new Gson().fromJson(json, type);
}
}
public List<ToDoItem> getList() {
return items;
}
public void addItem(ToDoItem item) {
items.add(item);
saveList();
}
public void saveList() {
SharedPreferences.Editor edit = savedData.edit();
edit.clear();
String json = new Gson().toJson(items);
edit.putString(TODO_ITEMS, json);
edit.apply();
}
}
todoItem.java
public class ToDoItem {
private String description;
private boolean isComplete;
public ToDoItem(String description,boolean isComplete) {
this.description = description;
this.isComplete = isComplete;
}
public String getDescription() {
return description;
}
public boolean isComplete() {
return isComplete;
}
public void toggleComplete() {
isComplete = !isComplete;
}
#Override
public String toString() {
return getDescription();
}
}
Activity_Main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<EditText
android:id="#+id/txtItem"
android:layout_width="240dp"
android:layout_height="wrap_content"
android:inputType="text"
android:hint="#string/hintTxtItem"
/>
<Button
android:id="#+id/btnAdd"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/lblBtnAdd"
android:layout_toRightOf="#id/txtItem"
/>
<TextView
android:id="#android:id/empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/txtItem"
android:text="#string/txtEmpty"
android:gravity="center_horizontal"
/>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/txtItem"
android:choiceMode="multipleChoice" >
</ListView>
<Button
android:id="#+id/btnDel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="#string/lblBtnDel" />
to_do_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<CheckBox
android:id="#+id/CheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"/>
<ListView
android:layout_weight="20"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="#+id/btnDel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="#string/lblBtnDel" />
Step1: Create activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="#+id/txtItem"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="text" />
<Button
android:id="#+id/btnAdd"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/txtItem"
android:text="Add" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ListView
android:id="#+id/lvTodo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:choiceMode="multipleChoice" />
<TextView
android:id="#android:id/empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:text="No data"
android:visibility="invisible" />
</RelativeLayout>
<Button
android:id="#+id/btnDel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Delete" />
</LinearLayout>
Step2: Create to todo_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:padding="10dp"
android:orientation="horizontal"
android:weightSum="1">
<TextView
android:id="#+id/tvTodoName"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Learn Android"
android:textSize="20sp" />
<CheckBox
android:id="#+id/cbChooseTodo"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Step3: Define Object Todo
public class ToDoItem {
private String description;
private boolean isComplete;
public ToDoItem(String description, boolean isComplete) {
this.description = description;
this.isComplete = isComplete;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isComplete() {
return isComplete;
}
public void setComplete(boolean complete) {
isComplete = complete;
}
}
Step4: Create TodoItemAdapter class
public class TodoItemAdapter extends ArrayAdapter<ToDoItem> {
private ArrayList<ToDoItem> arrayListTodo;
private LayoutInflater layoutInflater;
public TodoItemAdapter(Context context, int resource, ArrayList<ToDoItem> objects) {
super(context, resource, objects);
this.arrayListTodo = objects;
this.layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null){
holder = new ViewHolder();
convertView = layoutInflater.inflate(R.layout.todo_item, parent,false);
holder.tvTodoName = (TextView)convertView.findViewById(R.id.tvTodoName);
holder.cbTodoChoose = (CheckBox)convertView.findViewById(R.id.cbChooseTodo);
convertView.setTag(holder);
}else {
holder = (ViewHolder)convertView.getTag();
}
final ToDoItem toDoItem = arrayListTodo.get(position);
holder.tvTodoName.setText(toDoItem.getDescription());
holder.cbTodoChoose.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
toDoItem.setComplete(isChecked);
}
});
holder.cbTodoChoose.setChecked(toDoItem.isComplete());
return convertView;
}
public static class ViewHolder{
public TextView tvTodoName;
public CheckBox cbTodoChoose;
}
}
Step5: Process on the MainActivity class
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private ListView lvTodoItem;
private ArrayList<ToDoItem> toDoItems;
private TodoItemAdapter todoItemAdapter;
private Button btnDel;
private Button btnAdd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
}
private void initData(){
toDoItems = new ArrayList<>();
todoItemAdapter = new TodoItemAdapter(MainActivity.this, R.layout.todo_item, toDoItems);
lvTodoItem = (ListView)findViewById(R.id.lvTodo);
lvTodoItem.setAdapter(todoItemAdapter);
btnAdd = (Button)findViewById(R.id.btnAdd);
btnDel = (Button)findViewById(R.id.btnDel);
btnAdd.setOnClickListener(this);
btnDel.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnAdd:
addTodoItem();
break;
case R.id.btnDel:
deleteTodoItem();
break;
}
}
private void addTodoItem() {
}
private void deleteTodoItem() {
for (int i= toDoItems.size()-1; i>=0 ; i--){
ToDoItem toDoItem = toDoItems.get(i);
if (toDoItem.isComplete()){
toDoItems.remove(i);
}
}
todoItemAdapter.notifyDataSetChanged();
}
}
It is working fine. Thanks.
I am having problems in displaying cards dynamically from a recycler view. Here's my code.
CardActivity.java
public class CardActivity extends AppCompatActivity {
CardAdapter mAdapter;
RecyclerView mRecyclerView;
ArrayList<CardModel> data = new ArrayList<>();
public static String IMGS[] = {
"https://scontent.fmnl4-2.fna.fbcdn.net/v/t1.0-9/12540788_486126334923939_641652950626105372_n.jpg?oh=520090fa887ded912ddb7086fc69fc93&oe=57A04969",
"https://scontent.fmnl4-2.fna.fbcdn.net/t31.0-8/12973436_521081094761796_6679453535369186441_o.jpg",
"https://scontent.fmnl4-2.fna.fbcdn.net/v/t1.0-9/12191632_465602330309673_5460380145671805117_n.jpg?oh=51811b46395fee6e4bdb5394e6725591&oe=57D35DC3",
"https://scontent.fmnl4-2.fna.fbcdn.net/v/t1.0-9/10628472_397420133794560_5446805358922772021_n.jpg?oh=f23ab8761e05b2a50d0d0c9dec4d365b&oe=57DBF1CC",
"https://scontent.fmnl4-2.fna.fbcdn.net/t31.0-8/10697227_314766035393304_2937143993369666506_o.jpg",
"https://scontent.fmnl4-2.fna.fbcdn.net/v/t1.0-9/13133194_10154674163886840_3764712620850385571_n.jpg?oh=252cedf88040188f12ce99c29f3dd47e&oe=57DD7474"
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card);
for (int i = 0; i < IMGS.length; i++) {
CardModel cardModel = new CardModel();
cardModel.setTitle("Card Title: " + i);
cardModel.setDescription("This is a card description");
cardModel.setUrl(IMGS[i]);
data.add(cardModel);
}
Toolbar toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Cards");
mRecyclerView = (RecyclerView) findViewById(R.id.cards);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(CardActivity.this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setHasFixedSize(true);
mAdapter = new CardAdapter(CardActivity.this, data);
mRecyclerView.setAdapter(mAdapter);
}
public boolean onOptionsItemSelected(MenuItem item) {
onBackPressed();
return true;
}
}
CardModel.java
public class CardModel {
String url,title,description;
public CardModel() {
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
CardAdapter.java
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardHolder> {
private LayoutInflater inflater;
Context context;
List<CardModel> data = new ArrayList<>();
public CardAdapter(Context context, List<CardModel> data){
this.context = context;
this.data = data;
inflater = LayoutInflater.from(context);
}
#Override
public CardHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.card_layout,parent,false);
CardHolder cardHolder = new CardHolder(view);
return cardHolder;
}
#Override
public void onBindViewHolder(CardHolder holder, int position) {
holder.cardTitle.setText(data.get(position).getTitle());
holder.cardDescription.setText(data.get(position).getDescription());
Glide.with(context).load(data.get(position).getUrl())
.fitCenter()
.into(holder.cardImage);
}
#Override
public int getItemCount() {
return 0;
}
public static class CardHolder extends RecyclerView.ViewHolder {
ImageView cardImage;
TextView cardTitle;
TextView cardDescription;
public CardHolder(View cardView) {
super(cardView);
cardImage = (ImageView) cardView.findViewById(R.id.card_image);
cardTitle = (TextView) cardView.findViewById(R.id.card_title);
cardDescription = (TextView) cardView.findViewById(R.id.card_description);
}
}
}
activity_card.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.braudy.android.mesasixprofiler.CardActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<include layout="#layout/toolbar"/>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/cards"
android:layout_width="match_parent"
android:layout_height="fill_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</FrameLayout>
card_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:background="#FFFFFF"
android:padding="10dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:background="#ffffff">
<ImageView
android:layout_width="match_parent"
android:layout_height="150dp"
android:alpha=".7"
android:id="#+id/card_image"
android:background="#ffff66"
android:src="#drawable/img1"
android:scaleType="centerCrop"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Braudy"
android:paddingLeft="15dp"
android:textColor="#FFFFFF"
android:background="#707070"
android:alpha=".8"
android:textSize="25sp"
android:id="#+id/card_title"
android:layout_alignBottom="#+id/card_image"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:text="This is a description"
android:paddingTop="5dp"
android:paddingLeft="15dp"
android:textColor="#A9A9AF"
android:textSize="15sp"
android:id="#+id/card_description"
android:layout_below="#+id/card_image"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Change this
#Override
public int getItemCount() {
return 0;
}
to
#Override
public int getItemCount() {
return data.size();
}
change here-
#Override
public int getItemCount() {
return data.size();
}
You have to declare how much views you want to inflate in your view.