I am trying to add a RecyclerView to my app, but I am having lots of difficulties. I want the RecyclerView to have items of this layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/txtChords"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/txtLyrics"/>
</LinearLayout>
I put that into its own XML file, and declared the RecyclerView in the layout. But I don't know how to display the items
Thank you!!
I searched documentation and tutorials, but they all do something slightly different and too complicated when comparing to what I want to do. I just want to learn the basics of RecyclerViews and how to use them.
I will accept examples and any link
Please note that I am fairly new to android, and might need a simpler explanation
Recyclerview:
Recycler view is same as listview but recyclerview is added in android support lib for material design concept.
Example:
Add dependency for recyclerview
compile 'com.android.support:recyclerview-v7:23.1.0'
Add recyclerview in main layout file
<?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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/item_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
/>
</LinearLayout>
Make one item layout xml file (here is ur item file)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/txtChords"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/txtLyrics"/>
</LinearLayout>
Make one model class for each item in list.it can be any custom class.
public class Item {
private String name;
public Item(String n) {
name = n;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Now most important part is to make adapter for recyclerview:
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.codexpedia.list.viewholder.R;
import java.util.ArrayList;
public class ItemArrayAdapter extends RecyclerView.Adapter<ItemArrayAdapter.ViewHolder> {
//All methods in this adapter are required for a bare minimum recyclerview adapter
private int listItemLayout;
private ArrayList<Item> itemList;
// Constructor of the class
public ItemArrayAdapter(int layoutId, ArrayList<Item> itemList) {
listItemLayout = layoutId;
this.itemList = itemList;
}
// get the size of the list
#Override
public int getItemCount() {
return itemList == null ? 0 : itemList.size();
}
// specify the row layout file and click for each row
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(listItemLayout, parent, false);
ViewHolder myViewHolder = new ViewHolder(view);
return myViewHolder;
}
// load data in each row element
#Override
public void onBindViewHolder(final ViewHolder holder, final int listPosition) {
TextView item = holder.item;
item.setText(itemList.get(listPosition).getName());
}
// Static inner class to initialize the views of rows
static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView item;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
item = (TextView) itemView.findViewById(R.id.txtChords);
}
#Override
public void onClick(View view) {
Log.d("onclick", "onClick " + getLayoutPosition() + " " + item.getText());
}
}
This is simple adapter with minimum requirement method.
Now bind adapter with recyclerview
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import com.codexpedia.list.viewholder.R;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initializing list view with the custom adapter
ArrayList <Item> itemList = new ArrayList<Item>();
ItemArrayAdapter itemArrayAdapter = new ItemArrayAdapter(R.layout.list_item, itemList);
recyclerView = (RecyclerView) findViewById(R.id.item_list);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(itemArrayAdapter);
// Populating list items
for(int i=0; i<100; i++) {
itemList.add(new Item("Item " + i));
}
}
}
Hope this example will help u...
You can ask any question if u have any confusion.
You can refer this link if u want to make complex list
https://www.binpress.com/tutorial/android-l-recyclerview-and-cardview-tutorial/156
Related
I am trying to create StaggeredGrid with this code.
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.userprofile_photos,container,false);
setRetainInstance(true);
photosRecycler=view.findViewById(R.id.userPhotos_recycler);
layoutManager= new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
photosRecycler.setLayoutManager(layoutManager);
photosRecycler.setHasFixedSize(true);
adapter=new fetchPhoto_Adapter();
photosRecycler.setAdapter(adapter);
return view;
}
Fragment Layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/userPhotos_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll" />
</RelativeLayout>
Adapter
public class fetchPhoto_Adapter extends RecyclerView.Adapter<fetchPhoto_Adapter.ViewHolder>{
#NonNull
#Override
public fetchPhoto_Adapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
LayoutInflater inflater= (LayoutInflater) viewGroup.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.photogallery,viewGroup,false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(fetchPhoto_Adapter.ViewHolder viewHolder, int i) {
Glide.with(getActivity()).load(ImageList.get(i)).apply(new RequestOptions().centerCrop()).into(viewHolder.image);
}
#Override
public int getItemCount() {
return ImageList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView image;
public ViewHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.UserProfile_photoThumb);
}
}
}
Adapter Item Layout XML
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/UserProfile_photoThumb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
/>
I tried to make it StaggeredGrid but with above code and with lots of modification like
setting image scaletype to fitxy,centercrop,center and changing height to wrap_content and modifying Glide image loading code all showing same output. I wanted to make my StaggeredGrid Like below required output. Please help me out.
Well I have achieved this in one of my projects, so I am here sharing you some code snippet over here. Try it and let me know.
class DemoActivity : ActivityBase() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_demo_activity)
val layoutmanager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
layoutmanager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
rcv_staggered.layoutManager = layoutmanager
rcv_staggered.setHasFixedSize(true)
val listItem = ArrayList<DemoModel>()
// This is dummy url for reference and in this image url I was
// getting image with different width and height
val demoModel = DemoModel("https://i.picsum.photos/id/237/200/400.jpg", "Title 1")
val demoModel1 = DemoModel("https://i.picsum.photos/id/237/750/250.jpg", "Title 2")
val demoModel2 = DemoModel("https://i.picsum.photos/id/237/500/250.jpg", "Title 3")
val demoModel3 = DemoModel("https://i.picsum.photos/id/237/100/200.jpg", "Title 4")
listItem.add(demoModel)
listItem.add(demoModel1)
listItem.add(demoModel2)
listItem.add(demoModel3)
rcv_staggered.adapter = DemoAdapter(listItem)
}
}
Create recyclerView adapter same as we all do.
Load images using below snippet:
Glide.with(holder.img.context)
.load(listItem[holder.adapterPosition].color)
.placeholder(R.color.black_alpha_10)
.into(holder.img)
And this is my item layout for recyclerview
<?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="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"/>
</LinearLayout>
StaggeredGridLayoutManager Screenshot
Wrap your ImageView inside RelativeLayout, it should be Ok
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp">
<ImageView
android:id="#+id/UserProfile_photoThumb"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
I think their issues in glide code which you have used
Use this
Glide.with(mContext).load(imageList.get(i)).into(viewHolder.image);
Instead of this
Glide.with(getActivity()).load(ImageList.get(i)).apply(new RequestOptions().centerCrop()).into(viewHolder.image);
Also I have made some other changes in your code please check below example
Find the full code here
MainActivity2 code
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import android.os.Bundle;
import com.google.android.flexbox.FlexDirection;
import com.google.android.flexbox.FlexboxLayoutManager;
import com.google.android.flexbox.JustifyContent;
import java.util.ArrayList;
public class MainActivity2 extends AppCompatActivity {
RecyclerView photosRecycler;
ArrayList<String> imageList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
photosRecycler = findViewById(R.id.userPhotos_recycler);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
photosRecycler.setLayoutManager(layoutManager);
photosRecycler.setHasFixedSize(true);
imageList.add("https://i.stack.imgur.com/K8FFo.jpg?s=328&g=1");
imageList.add("https://i.stack.imgur.com/Bpdap.jpg?s=328&g=1");
imageList.add("https://i.stack.imgur.com/73QY4.jpg");
imageList.add("https://i.stack.imgur.com/Bpdap.jpg?s=328&g=1");
imageList.add("https://i.stack.imgur.com/K8FFo.jpg?s=328&g=1");
imageList.add("https://i.stack.imgur.com/Bpdap.jpg?s=328&g=1");
imageList.add("https://i.stack.imgur.com/K8FFo.jpg?s=328&g=1");
fetchPhoto_Adapter adapter = new fetchPhoto_Adapter(imageList, this);
photosRecycler.setAdapter(adapter);
}
}
activity_main2 of layout
<?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:orientation="vertical"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/userPhotos_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
fetchPhoto_Adapter
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import java.util.ArrayList;
public class fetchPhoto_Adapter extends RecyclerView.Adapter<fetchPhoto_Adapter.ViewHolder> {
ArrayList<String> imageList = new ArrayList<>();
Context mContext;
public fetchPhoto_Adapter(ArrayList<String> imageList, Context mContext) {
this.imageList = imageList;
this.mContext = mContext;
}
#NonNull
#Override
public fetchPhoto_Adapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View v = inflater.inflate(R.layout.photogallery, viewGroup, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(fetchPhoto_Adapter.ViewHolder viewHolder, int i) {
Glide.with(mContext).load(imageList.get(i)).into(viewHolder.image);
}
#Override
public int getItemCount() {
return imageList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView image;
public ViewHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.UserProfile_photoThumb);
}
}
}
photogallery layout
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/UserProfile_photoThumb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_margin="2dp"
android:scaleType="fitXY" />
OUTPUT
I created a listview with a custom adapter that allows me to have a list of items with checkboxes next to each item.
So I would like to look at the checkbox for the corresponding item in the list and see if it is checked and if it is, then set the value of boolean whiskey = false to true and so on for the other booleans.
It is very possible I have code in the wrong class or xml file, I've been trying to piece together things I've found on the internet. I'm new to android studio so its proving very difficult. I do have about a years worth of java experience though. I have all my code written in a working program on Eclipse, I am just having a hell of a time figuring out how to implement it into a working app.
Thanks in advance.
customAdapter.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import java.util.ArrayList;
public class customAdapter extends BaseAdapter {
private ArrayList<String> list = new ArrayList<String>();
private Context context;
public customAdapter(ArrayList<String> list, Context context) {
this.list = list;
this.context = context;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int pos) {
return list.get(pos);
}
public void setChecked(boolean isChecked){
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.activity2_listview, null);
}
//Handle TextView and display string from your list
TextView label = (TextView)view.findViewById(R.id.label);
label.setText(list.get(position));
//Handle buttons and add onClickListeners
CheckBox callchkbox = (CheckBox) view.findViewById(R.id.cb);
callchkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//update isChecked value to model class of list at current position
list.get(position).setChecked(isChecked);
}
});
return view;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
Main2Activity.java
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.Arrays;
import android.widget.CheckBox;
public class Main2Activity extends AppCompatActivity {
boolean Whiskey, Bourbon, Rum, Gin, Vodka, Tequila = false;
String [] userIngredients = {"Whiskey", "Bourbon", "Rum", "Gin", "Vodka", "Tequila", "Club Soda", "Lemon-Lime Soda",
"Ginger ale", "Cola", "Still mineral water", "Tonic Water", "Orange Juice", "Cranberry Juice", "Grapefruit Juice",
"Tomato Juice", "Cream or Half and Half", "Milk", "Ginger Beer", "PineApple Juice", "Lemons", "Limes", "Oranges"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ListView listView = (ListView) findViewById(R.id.userIngredients);
ArrayList<String> list = new ArrayList<String>(Arrays.asList(userIngredients));
listView.setAdapter(new customAdapter(list, Main2Activity.this));
}
}
activity_main2.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=".Main2Activity"
android:id="#+id/linearLayout">
<ListView
android:layout_width="419dp"
android:layout_height="558dp"
android:id="#+id/userIngredients"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView2"
tools:layout_conversion_absoluteHeight="731dp"
tools:layout_conversion_absoluteWidth="411dp" />
<TextView
android:id="#+id/textView2"
android:layout_width="374dp"
android:layout_height="60dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="Check Your Ingredients"
android:textSize="24sp"
app:fontFamily="#font/cinzel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
activity2_listview.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">
<TextView
android:id="#+id/label"
android:layout_width="323dp"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="ingredient"
android:textSize="20sp" />
<CheckBox
android:id="#+id/cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
i think you can do it with a BaseAdapter as well, but i suggest to use a RecyclerView instead.
I used support-v4 and recyclerview-v7 libs as following:
(Make sure that you are not developing AndroidX - check your gradle.properties of the entire project. It is very similar but uses other libraries though.)
build.gradle
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
...
dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:recyclerview-v7:28.0.0'
...
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.widget.RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Check Your Ingredients"
android:textAlignment="center" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_chooser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" >
</android.support.v7.widget.RecyclerView>
</android.widget.RelativeLayout>
In the activity2_listview you might want to do more design to the xml. It looks very basic now.
activity2_listview.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="wrap_content">
<TextView
android:id="#+id/listviewtextlabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="ingredient"
android:textSize="20sp" />
<CheckBox
android:id="#+id/listviewcheckbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
In the main class we implement a callback-listener for our custom onItemAction function. We pass the listener with adapter.setActionListener(this); and add the adapter to the RecyclerViewer.
MainActivity.java
public class MainActivity extends AppCompatActivity implements CustomAdapter.ItemActionListener {
boolean Whiskey, Bourbon, Rum, Gin, Vodka, Tequila = false;
String [] userIngredients = {"Whiskey", "Bourbon", "Rum", "Gin", "Vodka", "Tequila", "Club Soda", "Lemon-Lime Soda",
"Ginger ale", "Cola", "Still mineral water", "Tonic Water", "Orange Juice", "Cranberry Juice", "Grapefruit Juice",
"Tomato Juice", "Cream or Half and Half", "Milk", "Ginger Beer", "PineApple Juice", "Lemons", "Limes", "Oranges"};
CustomAdapter adapter;
RecyclerView.LayoutManager layoutManager;
RecyclerView recyclerListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
recyclerListView = (RecyclerView) findViewById(R.id.recycler_chooser);
ArrayList<String> list = new ArrayList<>();
list.addAll(Arrays.asList(userIngredients));
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerListView.setHasFixedSize(false);
layoutManager = new LinearLayoutManager(this);
recyclerListView.setLayoutManager(layoutManager);
System.out.println("list.size() " + list.size());
adapter = new CustomAdapter(list,MainActivity.this);
adapter.setActionListener(this);
recyclerListView.setAdapter(adapter);
} catch (Exception e){
e.printStackTrace();
}
}
// callback listener for your items
#Override
public void onItemAction(View view, CustomAdapter.CustomActions customAction, int position) {
final String itemName = adapter.getItem(position);
System.out.println(customAction + ": You clicked " + itemName + " on row number " + position);
switch(itemName){
case "Whiskey":
if(customAction== CustomAdapter.CustomActions.CHECK){
Whiskey=true;
}
else{
Whiskey=false;
}
System.out.println("Whiskey set to: " + Whiskey);
break;
case "Bourbon":
if(customAction== CustomAdapter.CustomActions.CHECK){
Bourbon=true;
}
else{
Bourbon=false;
}
System.out.println("Bourbon set to: " + Bourbon);
break;
//case xyz
// and so on
default:
System.out.println("Not programmed yet: " + itemName);
}
}
}
As said above i removed the BaseAdapter and replaced it with the RecyclerView. We had to implement a custom ViewHolder-class that contains each row in our RecyclerViewList. Within the ViewHolder we can call the method on our listener whenever a checkbox-change event occurs.
CustomAdapter.java
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {
//------ helper class for the viewholder
enum CustomActions{
CHECK,UNCHECK
}
// Provide a reference to the views for each row
public class CustomViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mTextView;
public CheckBox mCheckBox;
public CustomViewHolder(View v) {
super(v);
// the view element v is the whole linear layout element
CheckBox.OnCheckedChangeListener checkboxListenerForOneEntry = new CheckBox.OnCheckedChangeListener(){
#Override
public void onCheckedChanged(CompoundButton view, boolean isChecked) {
if (mItemActionListener != null) {
if(isChecked){
// this compoundbutton view element will be the checkbox
mItemActionListener.onItemAction(view, CustomActions.CHECK, getAdapterPosition());
}else{
mItemActionListener.onItemAction(view, CustomActions.UNCHECK, getAdapterPosition());
}
}
}
};
mTextView = v.findViewById(R.id.listviewtextlabel);
mCheckBox = v.findViewById(R.id.listviewcheckbox);
mCheckBox.setOnCheckedChangeListener(checkboxListenerForOneEntry);
}
}
//------
private ArrayList<String> list;
private Context context;
private LayoutInflater mInflater;
private ItemActionListener mItemActionListener;
public CustomAdapter(ArrayList<String> list, Context context) {
this.list = list;
this.context = context;
this.mInflater = LayoutInflater.from(this.context);
}
// allows clicks events to be caught
void setActionListener(ItemActionListener itemActionListener) {
this.mItemActionListener = itemActionListener;
}
// parent activity will implement this method to respond to click events
public interface ItemActionListener {
void onItemAction(View view, CustomActions customAction, int position);
}
// Create new views (invoked by the layout manager)
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = mInflater.inflate(R.layout.activity2_listview, parent, false);
return new CustomViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.mTextView.setText(list.get(position));
}
#Override // Return the size of your dataset (invoked by the layout manager)
public int getItemCount() {
return getCount();
}
public int getCount() {
return list.size();
}
public String getItem(int pos) {
return list.get(pos);
}
}
Feel free to use the code as you like.
For more info about the RecyclerView see the google docs: https://developer.android.com/guide/topics/ui/layout/recyclerview
I have cards with different width and I would like to create a Grid Layout where width = match the parent (filling the screen) and fixed height.
I would like to set the cards in the Grid layout so the number of columns changes accordingly to the width of the elements that can fit the row.
So the elements will be set in a horizontal row till they can fit the screen and then go to the next row, with a vertical scroll when they exceed the fixed height.
I am trying to use a Grid Layout but I don't know if it the suitable solution for this.
I use native Android.
Here a picture of it should look like:
Thanks.
You can use FlexboxLayoutManager
Add the following dependency to your build.gradle file:
implementation 'com.google.android:flexbox:1.0.0'
SAMPLE CODE
LAYOUT.XML
<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:orientation="vertical"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="250dp" />
</LinearLayout>
ACTIVTY CODE
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import com.google.android.flexbox.FlexDirection;
import com.google.android.flexbox.FlexboxLayoutManager;
import com.google.android.flexbox.JustifyContent;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
ArrayList<String> arrayList = new ArrayList<>();
DataAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
initArray();
FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(this);
layoutManager.setFlexDirection(FlexDirection.COLUMN);
layoutManager.setJustifyContent(JustifyContent.FLEX_END);
recyclerView.setLayoutManager(layoutManager);
adapter = new DataAdapter(this, arrayList);
recyclerView.setAdapter(adapter);
}
private void initArray() {
arrayList.add("ioreeoe");
arrayList.add("fghfgh");
arrayList.add("ftyjyjhghgh");
arrayList.add("jfgewrg");
arrayList.add("rwrewr");
arrayList.add("ghyjtyfghh");
arrayList.add("gfhfgh");
arrayList.add("gfhfht");
arrayList.add("retretret");
arrayList.add("retret");
arrayList.add("ioreeoe");
arrayList.add("fghfgh");
arrayList.add("ftyjyjhghgh");
arrayList.add("jfgewrg");
arrayList.add("rwrewr");
arrayList.add("ghyjtyfghh");
arrayList.add("gfhfgh");
arrayList.add("gfhfht");
arrayList.add("retretret");
arrayList.add("retret");
arrayList.add("ioreeoe");
arrayList.add("fghfgh");
arrayList.add("ftyjyjhghgh");
arrayList.add("jfgewrg");
arrayList.add("rwrewr");
arrayList.add("ghyjtyfghh");
arrayList.add("gfhfgh");
arrayList.add("gfhfht");
arrayList.add("retretret");
arrayList.add("retret");
}
}
Adapter code
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Created by nilesh on 3/4/18.
*/
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
Context context;
ArrayList<String> arrayList = new ArrayList<>();
public DataAdapter(Context context, ArrayList<String> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
#Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.custom_layout, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(DataAdapter.ViewHolder holder, int position) {
holder.title.setText(arrayList.get(position));
}
#Override
public int getItemCount() {
return arrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView title;
public ViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.nilu);
}
}
}
custom_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/nilu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/test"
android:padding="10dp"
android:textColor="#050505" />
</LinearLayout>
#drawable/test
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle" >
<corners android:radius="30dp"/>
<solid android:color="#d10e0e"/>
<stroke android:width="1dip" android:color="#070fe9" />
</shape>
</item>
</selector>
RESULT
You can use Staggered GridView libraries. For eg. https://github.com/etsy/AndroidStaggeredGrid
Edit:
add dependency in build.gradle and in your xml you can add:
<com.etsy.android.grid.StaggeredGridView
android:id="#+id/itemgridfragment_gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:column_count="2"
android:background="#color/white"
app:item_margin="#dimen/fragment_landingpage_8" />
</android.support.v4.widget.SwipeRefreshLayout>
MY PROBLEM
All views inside my RecyclerView, I am talking about elements(TextView and ImageView ....) are displayed well, normal but when i want to list all items inside the recyclerView with this:
for(int i=0;i<recyclerView.getChildCount();i++){
ids=ids+"-"+recyclerView.getChildAt(i).getId();
}
when i display ids always show me the same id which is the RelativeLayout id and it supose to display the id of the elements inside the RecyclerView as the TextView, ImageView and more
MY RESEARCH
i was following a video from slidenerd of
RecyclerView.OnItemTouchListener
and for him is working fine i dont know why for my is not working i was reading a lot about my problem to find the exact problem because:
First thing i did change the ids names for all my layouts to be different
Move the position of my code
Confirm that the data sent by MotionEvent e.getX() and y.getY() was correct and even thought i change the methods for getRaw
Read about RecyclerView class and find that there is not issue in this method findChildVIewUnder because all things that do are mathematicals
Read the id number of each important resource in R file an then convert it to dec to compare the prompt
I am close to the frustation
MY CODE
teacher_item
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/problem"
android:layout_width="328dp"
android:layout_height="130dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="10dp"
android:clickable="true"
android:background="#drawable/borders">
<ImageView
android:layout_width="90dp"
android:layout_height="100dp"
android:id="#+id/teacher_item_picture"
style="#style/TeacherItemImage" />
<RatingBar
android:layout_width="80dp"
android:layout_height="wrap_content"
android:id="#+id/teacher_item_ratingbar"
style="#style/TeacherItemRatingBar" />
<TextView
android:id="#+id/teacher_item_name"
android:layout_width="180dp"
android:layout_height="16.5dp"
style="#style/TeacherItemName" />
<TextView
android:id="#+id/teacher_item_courses"
android:layout_width="180dp"
android:layout_height="33dp"
style="#style/TeacherItemCourses" />
<TextView
android:id="#+id/teacher_item_faculties"
android:layout_width="180dp"
android:layout_height="33dp"
style="#style/TeacherItemFaculties" />
</RelativeLayout>
recyclerview.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:id="#+id/generic_listView"
android:layout_height="wrap_content"
style="#style/GenericListItem">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
teacherListFragment.javaimportant code
teacherListAdapter=new TeacherListAdapter(getActivity(),getData());
teacherListAdapter.setListener(this);
recyclerView.addItemDecoration(new RecyclerViewDivider(getActivity()));
recyclerView.setAdapter(teacherListAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addOnItemTouchListener(new RecyclerViewClickListener(getActivity(), recyclerView, new RecyclerViewClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Log.d("D", view.getId() + "-" + position);
}
}));
getData() returns an List, this code is inside onCreateView
TeacherListAdatper
package wan.wanmarcos.views.adapters;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import com.squareup.picasso.Picasso;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import wan.wanmarcos.R;
import wan.wanmarcos.managers.ItemAdapterListener;
import wan.wanmarcos.managers.ViewHolderSetters;
import wan.wanmarcos.models.Teacher;
import wan.wanmarcos.utils.Constants;
import wan.wanmarcos.views.widgets.CircleTransform;
public class TeacherListAdapter extends RecyclerView.Adapter<TeacherListAdapter.TeacherHolder> {
private LayoutInflater inflater;
private List<Teacher> teachers= Collections.emptyList();
private ItemAdapterListener itemAdapterListener;
public TeacherListAdapter(Context context,List<Teacher> teachers){
inflater= LayoutInflater.from(context);
this.teachers=teachers;
}
#Override
public TeacherHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=inflater.inflate(Constants.TEACHER_NEW_ITEM, parent, false);
TeacherHolder teacherCustomer = new TeacherHolder(view);
return teacherCustomer;
}
#Override
public void onBindViewHolder(TeacherHolder holder, int position) {
Teacher teacher=teachers.get(position);
holder.setElements(teacher);
}
public void setListener(ItemAdapterListener listener){
this.itemAdapterListener =listener;
}
#Override
public int getItemCount() {
return teachers.size();
}
public class TeacherHolder extends RecyclerView.ViewHolder implements ViewHolderSetters<Teacher>,View.OnClickListener{
private TextView teacherName;
private RatingBar teacherRating;
private ImageView teacherImage;
private TextView teacherCourses;
private TextView teacherAssumptions;
private Teacher current;
public TeacherHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
teacherName= (TextView) itemView.findViewById(R.id.teacher_item_name);
teacherRating=(RatingBar)itemView.findViewById(R.id.teacher_item_ratingbar);
teacherImage=(ImageView)itemView.findViewById(R.id.teacher_item_picture);
teacherCourses=(TextView)itemView.findViewById(R.id.teacher_item_courses);
teacherAssumptions=(TextView)itemView.findViewById(R.id.teacher_item_faculties);
}
#Override
public void setElements(Teacher elements) {
current=elements;
teacherName.setText(elements.getName());
teacherRating.setRating(elements.getRaiting());
teacherCourses.setText(itemView.getResources().getString(R.string.teacher_capabilities)+ elements.getFaculties());
teacherAssumptions.setText(itemView.getResources().getString(R.string.teacher_ped) + elements.getDescription());
Picasso.with(itemView.getContext()).load(elements.getImageUrl()).transform(new CircleTransform()).into(teacherImage);
}
#Override
public void onClick(View v) {
//itemAdapterListener.itemClicked(v,current);
}
}
}
WHAT I WANT IS: why child items of my RecyclerVIew are the layouts containers?
I need someone to help me Thanks
I want to create a list where the listview will display a textview and an icon for each row. The diagram should be as follows:
Other than that, The data is retrieved from the database. The attribute of "favorite" will be checked first and if true, then the image in listview will be assigned with favorite_icon.png. Else, no icon need to be assigned.
I have been search for the related answer and tutorial, but all of them is too different from what I want and I cannot understand it very much. Hope somebody here can help me. Thank you in advance.
Here is what I got after I have done my Homework
First we set up a custom layout for listview and also for the row of the listview we will use later.
Here is the custom_listview_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/customListView" />
</LinearLayout>
Here is the custom_listview_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:minHeight="64dp">
<ImageView
android:id="#+id/clv_imageView"
android:layout_width="32dp"
android:layout_height="32dp"
android:contentDescription="#string/empty"
android:layout_alignParentRight="true"
android:layout_marginLeft="9dp"
android:layout_alignParentTop="true"/>
<TextView
android:id="#+id/clv_textView"
android:layout_width="97dp"
android:layout_height="32dp"
android:layout_alignParentLeft="true"
android:gravity="center_vertical"
android:text="#string/tv_definition"
android:textIsSelectable="true" />
</RelativeLayout>
Then we need to customized how our Custom ArrayAdaptor will look and do.
But before that, make sure you have put your icon in the drawable folder.
Here is my MyPerformanceArrayAdapter.java
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MyPerformanceArrayAdapter extends ArrayAdapter<DefinitionObject>{
private List<DefinitionObject> entries;
private Activity activity;
public MyPerformanceArrayAdapter(Activity a, int textViewResourceId, List<DefinitionObject> entries) {
super(a, textViewResourceId, entries);
this.entries = entries;
this.activity = a;
}
public static class ViewHolder{
public TextView item1;
public ImageView item2;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if (v == null) {
LayoutInflater vi =
(LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.custom_listview_row, null);
holder = new ViewHolder();
holder.item1 = (TextView) v.findViewById(R.id.clv_textView);
holder.item2 = (ImageView) v.findViewById(R.id.clv_imageView);
v.setTag(holder);
}
else
holder=(ViewHolder)v.getTag();
final DefinitionObject custom = entries.get(position);
if (custom != null) {
holder.item1.setText(custom.getWord());
if(custom.getFav().equalsIgnoreCase("0"))
{
holder.item2.setImageResource(R.drawable.fav);
holder.item2.setVisibility(holder.item2.INVISIBLE);
}
else
{
holder.item2.setImageResource(R.drawable.fav2);
}
}
return v;
}
}
And lastly, here is my Activity to View the ListView using the CustomArrayAdaptor.
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ListView;
public class TempCLV extends Activity {
private MySQLiteDefinitionHelper db;
String tblName = "";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_listview_main);
Intent msjIntent = getIntent();
tblName = msjIntent.getStringExtra(WordDefinitionHomeActivity.TABLENAME2);
refresh();
}
public void refresh()
{
db = new MySQLiteDefinitionHelper(this);
final List<DefinitionObject> values = db.getAllWords(tblName);
ListView mylist = (ListView)findViewById(R.id.customListView);
MyPerformanceArrayAdapter adapter = new MyPerformanceArrayAdapter(this, R.id.customListView, values);
mylist.setAdapter(adapter);
}
}