Android add Views inside a ListView - android

how can I add Views inside a LinearLayout in a ListView? I want to display some additional information inside the ListView and I want to add them in a for loop going through the items to add. Here's the code I currently have:
Activity:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scrollbars="vertical"
android:layout_marginTop="0dp" />
</LinearLayout>
list_recycler:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="6dp"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp">
<TextView android:id="#+id/list_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/textColor"
android:textSize="16sp"
android:layout_alignParentLeft="true"/>
<TextView android:id="#+id/list_title_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/textColor"
android:textSize="16sp"
android:layout_alignParentLeft="true"/>
<!-- VIEWS SHOULD BE ADDED HERE -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</RelativeLayout>
</LinearLayout>
Adapter:
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.RecyclerViewHolder> {
public static class RecyclerViewHolder extends RecyclerView.ViewHolder {
TextView personName;
TextView personAge;
RecyclerViewHolder(View itemView) {
super(itemView);
personName = (TextView)itemView.findViewById(R.id.person_name);
personAge = (TextView)itemView.findViewById(R.id.person_age);
}
}
List<Items> list;
public RVAdapter(List<Items> list){
this.list = list;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_recycler, viewGroup, false);
return new RecyclerViewHolder(v);
}
#Override
public void onBindViewHolder(RecyclerViewHolder recyclerViewHolder, int i) {
recyclerViewHolder.personName.setText(persons.get(i).name);
recyclerViewHolder.personAge.setText(persons.get(i).age);
}
#Override
public int getItemCount() {
return persons.size();
}
}
Items:
public class Items {
String name;
String age;
public Items(String name, String age) {
this.name = name;
this.age = age;
}
}
How can I add views inside the LinearLayout in the ListView? Each LinearLayout in the different ListView Items should contain different views, so they can't all be the same.
How my data will look like:
ListView
Entry1
LinearLayout
SubEntry1
SubEntry2
SubEntry3
Entry2
LinearLayout
SubEntry1
SubEntry2
SubEntry3
Entry3
LinearLayout
SubEntry1
SubEntry2
SubEntry3
So Entry1..Entry3 are ListViews, all the subentries should be TextViews added by code into the LinearLayout inside its corresponding ListView entry

Give the layout an id, say #+id/item_content, then in your getViewdo:
itemContent = (LinearLayout)convertView.findViewById(R.id.item_content);
itemContent.removeAllViews();
//then you can add your views to the layouts depending on each item here using
itemContent.addView(yourView);
You can't simply loop over the ListView items and add content to it. That is what we have the adapter for. Update the data and notify the adapter tht the data has changed.
I'll advice you use RecyclerView in this context.
EDIT
What you added is not a data structure but your layout structure. Anyways, you should have this.
public class RowItem {
private final String title;
private final String desc;
private ArrayList<String> contents;
}
and then you'll do this;
itemContent = (LinearLayout)convertView.findViewById(R.id.item_content);
itemContent.removeAllViews();
//then you can add your views to the layouts depending on each item here using
for(String item : rowItem.getContents()){
TextView textView = new TextView(parent.getContext());
textView.setText(item);
itemContent.addView(textView);
}
Read RecyclerView and ExpandableListView

Related

Listview not clickable when adding an ImageButton (android - xml)

I have a layout for a listview item.
I added an ImageButton to the layout, as follows:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/tvTaskName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:textSize="20dp"
android:textColor="#000000"
android:layout_marginTop="5dp"
/>
<TextView
android:id="#+id/tvTaskDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Description"
android:textSize="14sp"
android:textColor="#0E2DF5"
android:layout_marginTop="40dp"
/>
<TextView
android:id="#+id/tvTaskStartTime"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Start time"
android:textSize="14sp"
android:textColor="#44FF00"
android:layout_marginHorizontal="100dp"
android:layout_marginTop="10dp"
/>
<TextView
android:id="#+id/tvTaskDeadLine"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Dead line"
android:textSize="14sp"
android:textColor="#44FF00"
android:layout_marginHorizontal="100dp"
android:layout_marginTop="40dp"
/>
<ImageButton
android:id="#+id/btnTaskDone"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginStart="345dp"
android:background="#drawable/done_button_state_selector"
/>
</FrameLayout>
The problem - when I add the ImageButton - the entire ListView becomes unclickable. I can only click the button.
I need both the ListView and the button to be clickable, because im using them for different purposes.
I tried putting the ImageButton in one FrameLayout, everything else in another FrameLayout, and both of the FrameLayouts in on big FrameLayout. Still nothing
I would be happy to hear any suggestions. Thanks!
I would use a recyclerView instead it allows for more flexibility, you can have your recyclerView in your xml code like so
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toolbar" />
Then you set it up like so with java code
RecyclerView recycler;
CustomAdapter adapter;
List<CustomModel> models = new ArrayList<>();
private DatabaseReference databaseReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_kids_search);
recycler= findViewById(R.id.recycler);
adapter = new CustomAdapter (models);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recycler.setLayoutManager(layoutManager);
recycler.setAdapter(searchAdapter);
}
So you create a model class to hold variables for each list item to show then you populate the models ArrayList with those models.
Here is how the the most important customAdapter class should look like
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
List<CustomModel> customModels;
Context context;
public CustomAdapter(List<ChildModel> childModels) {
this.childModels = childModels;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_child, parent, false);
context = parent.getContext();
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final CustomModel customModel = customModels.get(position);
holder.tvTaskName.setText(customModel.getTaskName());
holder.tvTaskDescription.setText(customModel.getDescreption());
holder.tvTaskStartTime.setText(customModel.getStartTime());
holder.tvTaskDeadLine.setText(customModel.getDeadLine());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Here the list item is clicked
}
});
holder.btnTaskDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Here the imageButton is clicked
}
});
}
#Override
public int getItemCount() {
return childModels.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvTaskName;
TextView tvTaskDescription;
TextView tvTaskStartTime;
TextView tvTaskDeadLine;
ImageButton btnTaskDone;
public ViewHolder(#NonNull View itemView) {
super(itemView);
tvTaskName = itemView.findViewById(R.id.tvTaskName);
tvTaskDescription = itemView.findViewById(R.id.tvTaskDescription);
tvTaskStartTime = itemView.findViewById(R.id.tvTaskStartTime);
tvTaskDeadLine = itemView.findViewById(R.id.tvTaskDescription);
btnTaskDone = itemView.findViewById(R.id.btnTaskDone);
}
}
}
Hope this helps

Null pointer exception on setOnClickListener()

I want to access from this fragment a view from another layout which is not part of the fragment. That is why i get NullPointerException.
How can i solve this?
Fragment code
public class Pacijenti_fragment extends Fragment {
//this is the JSON Data URL
public final static String MESSAGE_KEY= "com.example.android.app";
//a list to store all the products
List<Pacijent> pacijentList;
String id="";
String ID="";
//the recyclerview
RecyclerView recyclerView;
private SearchView searchView;
private PacijentiAdapter adapter;
Button btnPogled;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view=inflater.inflate(R.layout.pacijenti_fragment, container, false);
//getting the recyclerview from xml
recyclerView = (RecyclerView)view.findViewById(R.id.recylcerView);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new MyDividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL, 36));
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
//initializing the productlist
pacijentList = new ArrayList<>();
btnPogled=(Button)findViewById(R.id.btnDodaj); //here i make my button
Bundle b=getArguments();
this.id=b.getString("id");
System.out.println(id);
ID = this.id;
btnPogled.setOnClickListener(new View.OnClickListener(){ //here i get null pointer
#Override
public void onClick(View v) {
OnPogled();
}
});
//this method will fetch and parse json
//to display it in recyclerview
loadPacijenti();
return view;
}
This is another xml where I located my button
<?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:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/GornjiLayout"
>
<TextView
android:id="#+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="Jane"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Small"
android:textColor="#000000" />
<TextView
android:id="#+id/textViewSurname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_toRightOf="#id/textViewName"
android:text="Doe"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Small"
android:textColor="#000000"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/SredjiLayout"
android:layout_below="#id/GornjiLayout"
>
<TextView
android:id="#+id/textViewDateOfBirth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/textViewName"
android:layout_marginLeft="5dp"
android:layout_marginRight="150dp"
android:layout_marginTop="5dp"
android:text="21.05.1989"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Small"
android:textStyle="bold" />
<Button
android:id="#+id/buttonDodaj"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:text="Otvori" />
</LinearLayout>
<TextView
android:id="#+id/textViewAdress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/SredjiLayout"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:text="Some street 45, UnknownVille"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Small"
android:textStyle="bold" />
</RelativeLayout>
</LinearLayout>
I don't know how to access other xml from fragment. And this xml is separate file because it goes inside recyclerview with specific adapter that i wrote. and this button needs to be inside that recycler view because every button should pass id of every person from db.
Okay i got your point so basically what you're trying to do is access a button from another xml in your recycler view for that simply refer this code and do all changes in your adapter class here inside your oncreate view holder specify the xml file from which you'll be accessing the button:
public class ManagerTaskListAdapter extends RecyclerView.Adapter<ManagerTaskListAdapter.ProjectViewHolder> {
private ArrayList<Taskmsg> dataList;
private ArrayList<Project> projects;
Context mContext;
public ManagerTaskListAdapter(ArrayList<Taskmsg> dataList, Context mContext) {
this.dataList = dataList;
this.mContext=mContext;
}
#Override
public ProjectViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.man_task_list_item, parent, false);
return new ProjectViewHolder(view);
}
#Override
public void onBindViewHolder(ProjectViewHolder holder, int position) {
String fname=dataList.get(position).getEmpFirstName();
String lname=dataList.get(position).getEmpLastName();
String prdesc=dataList.get(position).getTaskDescription();
String pid= dataList.get(position).getProjectId().toString();
String em=dataList.get(position).getTaskCreatedBy();
String taskid=dataList.get(position).getTaskId().toString();
prdesc = prdesc.replaceAll("\\<.*?\\>", "");
holder.txttname.setText(dataList.get(position).getTaskName());
holder.txttdesc.setText(prdesc);
holder.txttaskcrt.setText(dataList.get(position).getTaskCreatedBy());
holder.txtempname.setText(fname +" "+ lname);
holder.itemView.setOnClickListener(v -> {
Intent in=new Intent(mContext,TaskDetails.class);
in.putExtra("tid",taskid);
in.putExtra("pid",pid);
in.putExtra("email",em);
mContext.startActivity(in);
});
}
#Override
public int getItemCount() {
return dataList.size();
}
class ProjectViewHolder extends RecyclerView.ViewHolder {
TextView txttname,txttdesc,txtempname,txttaskcrt;
ProjectViewHolder(View itemView) {
super(itemView);
txttname = (TextView) itemView.findViewById(R.id.tv_taskname);
txttaskcrt=itemView.findViewById(R.id.tv_taskcreatedby);
txttdesc = (TextView) itemView.findViewById(R.id.tv_taskdescription);
txtempname = (TextView) itemView.findViewById(R.id.tv_empname);
}
}
}
Just change one line of findviewById.
btnPogled=(Button)findViewById(R.id.btnDodaj)
to
btnPogled=(Button)view.findViewById(R.id.btnDodaj)

Reuse a inflated view, without inflating more than once

i want to reuse an inflated view just the same way a listView adapter does with convertView. Ive been lurking on the source code of adapters with no luck.
I need to add dinamically views depending on data to a recyclerItemView, now im inflating as much times as i need the view but having in mind its inside a recyclerView, this operation could become absurdly costly depending on the amount of data and scrolling behaviour of the user.
Other solution to my problem would be to create a listview inside the recyclerItem, so the listview wouldnt be scrollable, expands to maximum height depending on data added dynamically(making the listview container to expand to show all its data) and make the recyclerItem expand depending on its height.
ACTIVITY
public class Main1Activity extends AppCompatActivity {
RecyclerView recyclerView;
CustomAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
recyclerView = (RecyclerView) findViewById(R.id.recycler);
setUpRecycler();
}
private void setUpRecycler(){
Sample sample1 = new Sample("List of Items1");
Sample sample2 = new Sample("List of Items2");
Sample sample3 = new Sample("List of Items3");
List<Sample> sampleList = new ArrayList<>();
sampleList.add(sample1);
sampleList.add(sample2);
sampleList.add(sample3);
adapter = new CustomAdapter(this,sampleList);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:padding="30dp">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
MODEL
public class Sample {
String name;
public Sample(){}
public Sample(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
XML ITEMS
**item_list**
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="40dp">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
**item_smaple**
<?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:orientation="vertical">
<TextView
android:id="#+id/name"
android:layout_width="120dp"
android:layout_height="40dp"
android:layout_margin="10dp"
android:text="List of Items"
android:textSize="20sp"/>
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:orientation="vertical"/>
</LinearLayout>
ADAPTER
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private List<Sample> mySamples;
private Context mContext;
public CustomAdapter(Context context, List<Sample> mySamples) {
this.mContext = context;
this.mySamples = mySamples;
}
private Context getContext() {
return mContext;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public LinearLayout linearLayout;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
linearLayout = (LinearLayout) itemView.findViewById(R.id.linearLayout);
}
}
#Override
public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View contactView = inflater.inflate(R.layout.item_sample, parent, false);
ViewHolder viewHolder = new ViewHolder(contactView);
return viewHolder;
}
#Override
public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
Sample sample = mySamples.get(position);
holder.name.setText(sample.getName());
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.item_list, null, false);
for (int i = 0; i < 20; i++){
TextView textView = (TextView) v.findViewById(R.id.textView);
textView.setText("hello"+i);
holder.linearLayout.addView(v);
}
}
#Override
public int getItemCount() {
return mySamples.size();
}
}
Right now i´m inflating inside the loop. How could i modify view parameters to make it reusable to the framework?
My app crashes on the addView()
-->java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
The issue that you are referring to is the one which was addressed by creating RecyclerView which is an upgrade to ListView. What RecyclerView does is that it will create/inflate say 5-10 list item and when the user starts scrolling new listItem view(s) are not inflated infact just the data is updated inside the listItem.
This is a great explainer video of how recycler view actually works with a bit of code as well. https://www.youtube.com/watch?v=Wq2o4EbM74k
I hope this clears your doubt regarding the inflation issue.
My app crashes on the addView() -->java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
try:
#Override
public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
Sample sample = mySamples.get(position);
holder.name.setText(sample.getName());
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context
.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < 20; i++) {
View v = inflater.inflate(R.layout.item_list, holder.linearLayout, false);
TextView textView = (TextView) v.findViewById(R.id.textView);
textView.setText("hello" + i);
holder.linearLayout.addView(v);
}
}
itemSample.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="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_margin="10dp"
android:text="List of Items"
android:textSize="20sp"/>
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginLeft="30dp"
android:orientation="vertical"
android:isScrollContainer="true"
/>
</LinearLayout>
itemList.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="40dp"
android:isScrollContainer="true"
android:id="#+id/txt_cont"
>
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
You should try answer #

RecyclerView not scrolling to the bottom

I followed the recyclerview guidelines and built one for the app I am making, but it does not scroll to the bottom for some reason. I compared it with google code snippets, as well as other code snippets online and can't see the difference. I have posted a picture and the code I am using. I am using tabs, therefore the recyclerview is populated in a fragment.
What the app looks like:
http://imgur.com/H5uOLFR
the adapter class:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<Group> groups;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView groupName;
public TextView groupDate;
public TextView groupLocation;
public TextView className;
public ViewHolder(View v) {
super(v);
groupName = (TextView) v.findViewById(R.id.groupName);
groupDate = (TextView) v.findViewById(R.id.groupDate);
groupLocation = (TextView) v.findViewById(R.id.groupLocation);
className = (TextView) v.findViewById(R.id.className);
}
}
/*
* TODO: finish this method
*/
public void add(int position, String item) {
notifyItemInserted(position);
}
public void remove(String item) {
int position = groups.indexOf(item);
groups.remove(position);
notifyItemRemoved(position);
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(List<Group> groupsList) {
groups = groupsList;
Log.d("TEST", "Number of Groups: " +
Integer.toString(groups.size()));
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.group_view, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
final Group group = groups.get(position);
// holder.groupName.setText(group.getName());
holder.groupName.setText(group.getName());
holder.groupDate.setText(group.getFormattedDate());
holder.groupLocation.setText(group.getLocation());
holder.className.setText(group.getParent().getName());
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return groups.size();
}
}
The Fragment class:
public class groupsFragment extends Fragment implements GroupLeaver, GroupRetriever {
private RecyclerView rv;
private List<Group> groups;
private ProgressDialog progressDialog;
#Override
public void onCreate(Bundle savedInstance){
super.onCreate(savedInstance);
Log.d("TEST", "Entered onCreate");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
AppMain.getController().retrieveGroups(groupsFragment.this);
Log.d("TEST", "Entered onCreateView");
View rootView = inflater.inflate(R.layout.groups_fragment, container, false);
rv = (RecyclerView) rootView.findViewById(R.id.recyclerView);
rv.setLayoutManager(new LinearLayoutManager(getActivity()));
Log.d("TEST", "Size of LIST: " + Integer.toString(groups.size()));
MyAdapter adapter = new MyAdapter(groups);
rv.setAdapter(adapter);
return rootView;
}
#Override
public void onMyGroupsFound(List<Group> groups) {
Log.d("TEST", "Entered onMyGroupsFound");
Logg.info(this.getClass(), "Found %d groups for member %s", groups.size(), User.getCurrentUser().getDisplayName());
this.groups = groups;
}
#Override
public void onGroupLeft(Group oldGroup) {
}
#Override
public void onGroupLeftFailed(Group group, ParseException e) {
}
}
The xml layout for the recyclerview:
<?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="match_parent"
android:orientation="vertical"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#null"/>
</FrameLayout>
The xml layout for the recyclerview items:
<?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"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:orientation="horizontal">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="3"
android:orientation="vertical">
<TextView
android:id="#+id/groupName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Group Name"
/>
<TextView
android:id="#+id/groupDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Group Date"
/>
<TextView
android:id="#+id/groupLocation"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Group Location"
/>
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="#+id/className"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="right"
android:text="Class Name"
/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
You can use these lines to scroll recyclerview to:
list.add(0, group);
adapter.notifyItemInserted(0);
recyclerview.scrollToPosition(0);
Thanks to everyone who responded, but turns out the problem was the version of RecyclerView I was compiling.
Previously I was compiling this
compile 'com.android.support:recyclerview-v7:22.0.0'
But I changed it to this and it worked
compile 'com.android.support:recyclerview-v7:22.2.0'
Credits to #roi divon for the answer: CoordinatorLayout with RecyclerView & CollapsingToolbarLayout
Maybe adding these lines to the recyclerView will do:
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbars="vertical"
This is my recyclerView which is working:
<android.support.v7.widget.RecyclerView
android:id="#+id/menuRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbars="vertical"/>
I am not sure but I think problem might be Framelayout You can try with Linearlayout instead of Framelayout in your xml layout for the recyclerview items

Populate RecyclerView and CardView with ArrayList<String>

I have a cardview with 2 textviews inside. The first textview displays the name of a contact and the second displays the phone number. I want to use an ArrayList to populate the recyclerview.
I'm still new to Android programming so I don't know how to implement RecyclerView or make an adapter that will alternate between name and number filling in the textview. How can I achieve this?
My CardView (card_row.xml)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:clickable="true"
android:orientation="horizontal"
card_view:cardCornerRadius="0dp"
card_view:cardUseCompatPadding="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:selectableItemBackground"
android:orientation="vertical">
<TextView
android:id="#+id/text1"
android:layout_width="match_parent"
android:layout_height="38dp"
android:layout_margin="5dp"
android:gravity="left"
android:textColor="#android:color/black"
android:textSize="24sp" />
<TextView
android:id="#+id/text2"
android:layout_width="match_parent"
android:layout_height="37dp"
android:layout_margin="5dp"
android:layout_below="#id/text1"
android:textColor="#android:color/darker_gray"
android:textSize="18sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
EDIT:
I made 2 arraylists, one for names and the other for numbers. Now I how do I populate the recyclerview?
OK First make a inner class. This will be your adapter change all the id:
class Adapter extends RecyclerView.Adapter<LibraryAdapter.MyViewHolder>{
LayoutInflater inflater;
public LibraryAdapter(Context context){
inflater = LayoutInflater.from(context);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view =inflater.inflate(R.layout.main_exerciselibrary_fragment_singlerow,parent,false);
MyViewHolder holder=new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Exercises exercises = new Exercises(getActivity());
ArrayList<String> arrayList1 = new ArrayList<String>();
ArrayList<String> arrayList2 = new ArrayList<String>();
holder.Name.setText(arrayList1.get(position));
holder.PhoneNumber.setText(arrayList2.get(position));
}
#Override
public int getItemCount() {
return array.lenght;
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView Name, PhoneNumber;
CardView card;
public MyViewHolder(View itemView) {
super(itemView);
PhoneNumber= (TextView) itemView.findViewById(R.id.imageViewPicLibrary);//change Here
Name = (TextView) itemView.findViewById(R.id.textViewExerciseLibraryExerciseName);//change Here
card= (CardView) itemView.findViewById(R.id.card_view_ex_lib);//change Here
card.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//OnClick
}
});
}
}
}
I think this is all.

Categories

Resources