List Item aligninment issue with Recycler View - android

One of my project i used ListView to show the list of items to the user and it is working like a charm. Now as a try i replaced the Listview with the RecyclerView and succeed to show the items to the user.
Well the problem is when ever i used a customized Listview item it is working with the Listview. But when i try to load the same with RecyclerView it is not aligning/ fitting for the screen.
Here is my expected result.. I achieved this by using ListView.. Here is the Result what i am expecting
but when i used RecyclerView it is showing as below.
But i am using the same listview_item xml for both views to load..
Here is my listview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listrow"
android:layout_width="match_parent"
android:layout_height="55dp"
android:weightSum="9"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal" >
<ImageView
android:id="#+id/imageView2"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:layout_weight="0.5"
android:src="#drawable/green" />
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center"
android:textColor="#000000"
android:textSize="20sp" />
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1.5"
android:gravity="center"
android:textColor="#000000"
android:textSize="20sp" />
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center"
android:textColor="#000000"
android:textSize="20sp" />
<TextView
android:id="#+id/textView4"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center"
android:textColor="#000000"
android:textSize="20sp" />
<TextView
android:id="#+id/textView5"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center"
android:textColor="#000000"
android:textSize="20sp" />
<ImageView
android:id="#+id/imageView_followupone"
android:layout_width="0dp"
android:layout_height="22dp"
android:layout_gravity="center"
android:layout_weight="1"
android:src="#drawable/nored" />
<ImageView
android:id="#+id/imageView_followuptwo"
android:layout_width="0dp"
android:layout_height="22dp"
android:layout_gravity="center"
android:layout_weight="1"
android:src="#drawable/yesgreen" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="0dp"
android:layout_height="55dp"
android:layout_weight="1"
android:gravity="center"
android:src="#drawable/finalise" />
</LinearLayout>
Adapter Class:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private static ArrayList<SearchParms> itemData;
private static Context abc;
private int durationOfPatientRecord;
View itemLayoutView;
public MyAdapter( ArrayList<SearchParms> items, Context context) {
this.itemData = items;
this.abc=context;
}
// Create new views (invoked by the layout manager)
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
itemLayoutView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_row_serch, null);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
// Replace the contents of a view (invoked by the layout manager)
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
// - get data from your itemsData at this position
// - replace the contents of the view with that itemsData
SearchParms item = itemData.get( position );
viewHolder.textView1.setText( item.getPartcipantId());
viewHolder.textView2.setText( item.getParticipantName());
viewHolder.textView3.setText( "" + item.getAge());
viewHolder.textView4.setText( item.getCreateDate());
viewHolder.imgView1.setImageResource( R.drawable.finalise );
viewHolder.imgView2.setImageResource( R.drawable.yesgreen );
viewHolder.imgView3.setImageResource( R.drawable.yesgreen );
itemLayoutView.setBackgroundColor( Color.parseColor( "#15ffffff" ) );
}
}
// inner class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
public TextView textView1, textView2,textView3, textView4, textView5;
public ImageView imgView1, imgView2, imgView3, imgView4;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
textView1 = (TextView) itemLayoutView.findViewById(R.id.textView1);
textView2 = (TextView) itemLayoutView.findViewById(R.id.textView2);
textView3 = (TextView) itemLayoutView.findViewById(R.id.textView3);
textView4 = (TextView) itemLayoutView.findViewById(R.id.textView4);
textView5 = (TextView) itemLayoutView.findViewById(R.id.textView5);
imgView1 = (ImageView) itemLayoutView.findViewById(R.id.imageView1);
imgView2 = (ImageView) itemLayoutView.findViewById(R.id.imageView_followupone);
imgView3 = (ImageView) itemLayoutView.findViewById(R.id.imageView_followuptwo);
imgView4 = (ImageView) itemLayoutView.findViewById(R.id.imageView2);
itemLayoutView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int i=getAdapterPosition();
SearchParms item = itemData.get( i );
Toast.makeText(abc, "You Selected:: " +item.getParticipantName(), 3000).show();
}
}
// Return the size of your itemsData (invoked by the layout manager)
#Override
public int getItemCount() {
return itemData.size();
}
}
where it is making problem. is there any type of limitation for using RecyclerView? Curious to know about this. Thanks

Instead of setting your view like this:
itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.list_row_serch, null);
Do the following:
itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.list_row_serch, parent, false);

Related

RecyclerView to be Scrolled horizontally with the width

I have more items to show in the cardView horizontally inside a recyclerView and I have more cards veritically.
I tried to place cardView inside a HorizontalScrollView, It worked to scroll the idividual card. I wanted to scroll the entire RecyclerView to be scrolled to see right end items.
I tried with the RecyclerView inside a HorizontalScroolView not worked. RecyclerView inside a NestedScrollView not worked.
The RecyclerView is in a fragment. Inside the viewPager tabLayout, this is one of the fragment
fragment xml:
<?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="wrap_content"
android:orientation="horizontal">
<android.support.v7.widget.RecyclerView
android:id="#+id/record_recycler"
android:layout_width="550dp"
android:scrollbars="horizontal"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
Adapter:
public class TestAdapter extends RecyclerView.Adapter{
private List<Model> items;
Context context;
public TestAdapter(Context con, List<Model> itemslist) {
context=con;
this.items = itemslist;
}
#Override
public int getItemViewType(int position) {
return items.get(position).getUnique();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType==0)
return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.cricketrank_record_valuecard, parent, false));
else
return new MyViewHolder1(LayoutInflater.from(parent.getContext()).inflate(R.layout.cricketrank_record_titlecard, parent, false));
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof MyViewHolder)
try{
((MyViewHolder)holder).bindViewHolder(position);
}catch (Exception e){
Log.e(Constant.Tag,e.toString());
}
else if(holder instanceof MyViewHolder1)
try{
((MyViewHolder1)holder).bindViewHolder(position);
}catch (Exception e){
Log.e(Constant.Tag,e.toString());
}
}
#Override
public int getItemCount() {
return items.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
public TextView text,text1,text2,text3,text4,text5;
public View mCardView;
public MyViewHolder(View view) {
super(view);
text1 = (TextView) view.findViewById(R.id.text1);
text2 = (TextView) view.findViewById(R.id.text2);
text3 = (TextView) view.findViewById(R.id.text3);
text4 = (TextView) view.findViewById(R.id.text4);
}
public void bindViewHolder(int position) {
text1.setText(items.get(position).getTeam());
text2.setText(items.get(position).getRank());
text3.setText(items.get(position).getMatches());
text4.setText(items.get(position).getPoints());
}
}
}
public class MyViewHolder1 extends RecyclerView.ViewHolder{
public TextView text,text1,text2,text3,text4,text5;
public RelativeLayout rl;
public MyViewHolder1(View view) {
super(view);
text = (TextView) view.findViewById(R.id.text);
text1 = (TextView) view.findViewById(R.id.text1);
text2 = (TextView) view.findViewById(R.id.text2);
text3 = (TextView) view.findViewById(R.id.text3);
text4 = (TextView) view.findViewById(R.id.text4);
rl = (RelativeLayout) view.findViewById(R.id.rl);
}
public void bindViewHolder(int position) {
text1.setText(items.get(position).getTeam());
text2.setText(items.get(position).getRank());
text3.setText(items.get(position).getMatches());
text4.setText(items.get(position).getPoints());
}
}
}
MainActivity:
RecyclerView record_recycler= (RecyclerView) view.findViewById(R.id.record_recycler);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
record_recycler.setLayoutManager(mLayoutManager);
record_recycler.setItemAnimator(new DefaultItemAnimator());
TestAdapter adapter = new TestAdapter(getActivity(), list);
record_recycler.setAdapter(adapter);
I think you are trying to scroll the recyclerview in two direction. Vertical is usual scroll of recylerview and in horizontally, the scrolling view if it is not fit with the mentioned width. Right?
If you are trying this, then I think it is not possible to scroll like you think.
You can scroll the recycler view in both the directions with different views holding on them.
As you said the scrolling of cardview is possible, by default it won't have any scrolling properly normally. So it will scroll to show the card content completely to the user if they are not seeing completely and you set the scrolling view to scroll.
The possible way is, keep the views vertically with their field name and value. If you want to create more, then add one more row to accommodate the values down.
Have a look below:
<android.support.v7.widget.CardView
android:id="#+id/card"
android:layout_marginTop="2dp"
android:layout_marginBottom="4dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/layout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/layout1"
android:orientation="horizontal">
<TextView
android:text="One"
android:textSize="#dimen/font_itemsrow_13dp"
android:layout_weight=".11"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView
android:text="Two"
android:textSize="#dimen/font_itemsrow_13dp"
android:layout_weight=".11"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView
android:text="Three"
android:textSize="#dimen/font_itemsrow_13dp"
android:layout_weight=".24"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView
android:text="Four"
android:textSize="#dimen/font_itemsrow_13dp"
android:layout_weight=".11"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView
android:text="Five"
android:textSize="#dimen/font_itemsrow_13dp"
android:layout_weight=".17"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView
android:text="Six"
android:textSize="#dimen/font_itemsrow_13dp"
android:layout_weight=".26"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="#+id/layout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/padding_3dp"
android:layout_below="#+id/layout2"
android:orientation="horizontal">
<TextView
android:id="#+id/one"
android:textSize="#dimen/font_itemsrow_14dp"
android:textColor="#color/black"
android:layout_weight=".11"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/two"
android:textSize="#dimen/font_itemsrow_14dp"
android:textColor="#color/black"
android:layout_weight=".11"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/three"
android:textSize="#dimen/font_itemsrow_14dp"
android:textColor="#color/black"
android:layout_weight=".24"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/four"
android:textSize="#dimen/font_itemsrow_14dp"
android:textColor="#color/black"
android:layout_weight=".11"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/five
android:textSize="#dimen/font_itemsrow_14dp"
android:textColor="#color/black"
android:layout_weight=".17"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/six"
android:textSize="#dimen/font_itemsrow_14dp"
android:textColor="#color/black"
android:layout_weight=".26"
android:paddingRight="3dp"
android:layout_width="0dp"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
....// Add extra title Row
</LinearLayout>
<LinearLayout
....// Add extra Values Row
</LinearLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
You can archive it with LayoutManager refrence, with 3 arguments, in your case, change MainActivity a little bit, it will look this:
RecyclerView.LayoutManager mLayoutManager
= new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
Like documentation says, second argument define orientation:
/**
* #param context Current context, will be used to access resources.
* #param orientation Layout orientation. Should be {#link #HORIZONTAL} or {#link
* #VERTICAL}.
* #param reverseLayout When set to true, layouts from end to start.
*/

Adding components dynamically to RecyclerView

I'm displaying daily events. The number of events/day is variable. Each item in the RecView is a Day which should contain as many views as the number of events.
Here is one item's layout:
<?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="match_parent"
android:id="#+id/llDay">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvDay"
android:text="TODAY"
android:layout_gravity="center_horizontal"
android:layout_marginTop="15dp"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvNothing"
android:text="No events"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textStyle="italic"
android:visibility="gone"/>
</LinearLayout>
I'd like to add views to the llDay dynamically.
Here is my Adapter:
public class DiaryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
ArrayList<ArrayList<Displayable>> diaryEvents = new ArrayList<>();
Context context;
public DiaryAdapter(ArrayList<ArrayList<Displayable>> diaryEvents, Context context) {
this.diaryEvents = diaryEvents;
this.context = context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_day_diary, parent, false);
DiaryDayViewHolder viewHolder = new DiaryDayViewHolder(viewGroup);
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
DiaryDayViewHolder viewHolder = (DiaryDayViewHolder) holder;
ArrayList<Displayable> events = diaryEvents.get(position);
if (events.size() > 0){
addLayouts(events, viewHolder);
}
else{
viewHolder.tvNothing.setVisibility(View.VISIBLE);
}
}
#Override
public int getItemCount() {
return diaryEvents.size();
}
private void addLayouts(ArrayList<Displayable> events, DiaryDayViewHolder viewHolder) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
for (Displayable event : events) {
switch (event.getEventType()){
case Types.TYPE_TEACHING:
TeachingDiaryLayout teachingDiaryLayout = new TeachingDiaryLayout(context);
teachingDiaryLayout.setLayoutParams(params);
teachingDiaryLayout.setViews((Teaching) event);
viewHolder.llDay.addView(teachingDiaryLayout);
viewHolder.tvDay.setText("DAY"); // TODO: day + date
break;
case Types.TYPE_TASK: // TODO
break;
case Types.TYPE_EXAM: // TODO
break;
}
}
}
}
When the RecyclerView is displayed first, the events are displayed correctly, but after scrolling some events are displayed multiple times. I know that the problem is caussed by calling the addLayouts(...) in the onBindViewHolder(...) but I don't know how to create the correct amount of views for each day.
UPDATE: ViewHolder added:
public static class DiaryDayViewHolder extends RecyclerView.ViewHolder {
LinearLayout llDay;
TextView tvDay;
TextView tvNothing;
public DiaryDayViewHolder(View itemView) {
super(itemView);
llDay = (LinearLayout) itemView.findViewById(R.id.llDay);
tvDay = (TextView) itemView.findViewById(R.id.tvDay);
tvNothing = (TextView) itemView.findViewById(R.id.tvNothing);
}
}
Ok finally figured it out.
Firstly change your layout to:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/llDay">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvDay"
android:text="TODAY"
android:layout_gravity="center_horizontal"
android:layout_marginTop="15dp"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvNothing"
android:text="No events"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textStyle="italic"
android:visibility="gone"/>
<LinearLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/llDay1"/>
</LinearLayout>
now in your view holder add another LinearLayout parameter:
LinearLayout llDay,llday1;
and inside the addLayouts method change:
viewHolder.llDay.addView(teachingDiaryLayout);
to
viewHolder.llDay1.addView(teachingDiaryLayout);
Also before the for loop add
viewHolder.llDay1.removeAllViews();
for (Displayable event : events)

Get "No results" Message Custom Adapter ListView Android

I am having a problem to set a "No results" message when getCount() returns 0.
I have a custom layout for the listview, and I simply want to get a "No Results" textview when there is no data on the listview.
Any idea how to achieve this?
I saw something with a empty id, but that needs to be on a listview, since this is a custom layout, it doesn't have that "tag".
Custom Adapter Code:
public class ListScheduleAdapter extends BaseAdapter {
Context context;
protected List<Schedule> listSchedules;
LayoutInflater inflater;
public ListScheduleAdapter(Context context, List<Schedule> listSchedules) {
this.listSchedules = listSchedules;
this.inflater = LayoutInflater.from(context);
this.context = context;
}
public int getCount() {
return listSchedules.size();
}
public Schedule getItem(int position) {
return listSchedules.get(position);
}
public long getItemId(int position) {
return listSchedules.get(position).getCod_Horario();
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = this.inflater.inflate(R.layout.layout_list_item,
parent, false);
holder.txtTeacher = (TextView) convertView
.findViewById(R.id.txt_teacher);
holder.txtDayofWeek = (TextView) convertView
.findViewById(R.id.txt_dayofweek);
holder.txtSubject = (TextView) convertView
.findViewById(R.id.txt_subject);
holder.txtTime = (TextView) convertView
.findViewById(R.id.txt_time);
holder.txtRoom = (TextView) convertView
.findViewById(R.id.txt_room);
holder.txtClass = (TextView) convertView
.findViewById(R.id.txt_class);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Schedule sche = listSchedules.get(position);
String fullTeacher = sche.getProfessor();
String[] names = fullTeacher.split(" ");
holder.txtTeacher.setText(names[0] + " " + names[names.length-1]);
holder.txtDayofWeek.setText(sche.getDia_Semana());
holder.txtSubject.setText(sche.getDisciplina());
holder.txtTime.setText(sche.getT_Entrada() + "h-" + sche.getT_Saida()+"h");
holder.txtRoom.setText(sche.getSala());
holder.txtClass.setText(sche.getTurma());
return convertView;
}
private class ViewHolder {
TextView txtTeacher;
TextView txtDayofWeek;
TextView txtSubject;
TextView txtTime;
TextView txtRoom;
TextView txtClass;
}
}
Fragment Code (method called on a async OnPostExecute method):
private void populateListView() {
ListScheduleAdapter adapter = new ListScheduleAdapter(getActivity(), ScheduleList);
listviewHorarios.setAdapter(adapter);
}
Layout code:
<?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="wrap_content"
android:orientation="horizontal"
android:padding="8dp" >
<LinearLayout
android:id="#+id/layout_row1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/txt_teacher"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="normal" />
<TextView
android:id="#+id/txt_dayofweek"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:id="#+id/layout_row2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/layout_row1"
android:orientation="horizontal" >
<TextView
android:id="#+id/txt_subject"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="normal" />
<TextView
android:id="#+id/txt_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:id="#+id/layout_row3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/layout_row2"
android:orientation="horizontal" >
<TextView
android:id="#+id/txt_room"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="normal" />
<TextView
android:id="#+id/txt_class"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="normal" />
</LinearLayout>
<TextView
android:id="#+id/empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawablePadding="5dp"
android:gravity="center"
android:text="#string/no_data_available"
android:textColor="#android:color/black"
android:visibility="gone" />
</RelativeLayout>
add
<TextView
android:id="#+id/empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawablePadding="5dp"
android:gravity="center"
android:text="#string/no_data_available"
android:textColor="#android:color/black"
android:visibility="gone" />
to the same layout where you declared your ListView (wrap both in a FrameLayout)
on the ListView's instance call
listView.setEmptyView(findViewById(R.id.empty));
when the adapter is empty, you will see the TextView apper
add TextView to your listview layout and setVisibility of it to GONE and check the adapter:
if(adapter==null){
listView.setVisiblity(View.GONE);
tvEmpty.setVisiblity(View.VISIBLE);
}
hope this will help.

Row in listview not preserve the makeover and appears repeated

I have a list that when you click on the row on the right side the layout with the icon is changed by other. This makes it well but when I scrolling in the list, I notice there are rows with the same icon without do click. Also, if I scroll quickly these same icons are lost and are built differently. I think it's on the reuse of cells but I can not find the solution. What I want is that the image stays active only in the row where clicka.
Thanks!!
Adapter class:
public class ListadoVotantesArrayAdapter extends ArrayAdapter<Votante> {
private Context context;
private LayoutInflater inflater;
private ArrayList<Votante> listaVotantes;
private int rowLayout;
private View mConverView;
public ListadoVotantesArrayAdapter(Context context, int resource, ArrayList<Votante> objects) {
super(context, resource,objects);
this.context = context;
this.inflater = LayoutInflater.from(context);
this.listaVotantes = objects;
this.rowLayout = resource;
}
public int getCount(){
return this.listaVotantes.size();
}
public Votante getVotante(int position){
return this.listaVotantes.get(position);
}
private static class ViewHolder {
public TextView lblName;
public TextView lblLastName;
public TextView lblDni;
public TextView lblVoterNumber;
public RelativeLayout lytVoted;
public RelativeLayout lytCanVote;
public RelativeLayout lytUndo;
}
public View getView(int position, View converView, ViewGroup parent) {
final ViewHolder viewHolder;
mConverView = converView;
if (mConverView == null){
viewHolder = new ViewHolder();
this.mConverView = inflater.inflate(this.rowLayout, parent, false);
if (mConverView != null){
viewHolder.lblName = (TextView) mConverView.findViewById(R.id.lblVoterName);
viewHolder.lblLastName = (TextView) mConverView.findViewById(R.id.lblVoterLastName);
viewHolder.lblDni = (TextView) mConverView.findViewById(R.id.lblDni);
viewHolder.lblVoterNumber = (TextView) mConverView.findViewById(R.id.lblNumber);
viewHolder.lytVoted = (RelativeLayout) mConverView.findViewById(R.id.lytVoted);
viewHolder.lytCanVote = (RelativeLayout) mConverView.findViewById(R.id.lytCanVote);
viewHolder.lytUndo = (RelativeLayout) mConverView.findViewById(R.id.lytUndo);
mConverView.setTag(viewHolder);
}
}else{
viewHolder = (ViewHolder) mConverView.getTag();
}
Votante votante = getVotante(position);
viewHolder.lblName.setText(votante.getNombre());
viewHolder.lblLastName.setText(votante.getApellidos());
viewHolder.lblDni.setText(votante.getDni());
viewHolder.lblVoterNumber.setText(""+votante.getNumVotante());
if (votante.getVotado()){
viewHolder.lytVoted.setVisibility(View.VISIBLE);
viewHolder.lytCanVote.setVisibility(View.GONE);
}else{
viewHolder.lytVoted.setVisibility(View.GONE);
viewHolder.lytCanVote.setVisibility(View.VISIBLE);
}
mConverView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.lytUndo.setVisibility(View.VISIBLE);
notifyDataSetChanged();
}
});
return mConverView;
}
}
Layout Row:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lyt_voter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="1dp">
<RelativeLayout
android:id="#+id/lytVoterNumber"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:background="#color/lightBlueItemList">
<TextView
android:id="#+id/lblNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="1999"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
<LinearLayout
android:id="#+id/lytVoterData"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/lytCanVote"
android:layout_toRightOf="#+id/lytVoterNumber"
android:layout_toStartOf="#+id/lytCanVote"
android:background="#color/whiteItemList"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="#+id/lblVoterLastName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Suarez Garcia de la Serna"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/lblVoterName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="José Carlos"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/lblDni"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="44950962S"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<RelativeLayout
android:id="#+id/lytCanVote"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentRight="true"
android:background="#color/yellowItemList"
android:minHeight="30dp"
android:minWidth="30dp">
<ImageView
android:id="#+id/imgVote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/flecha" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/lytVoted"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentRight="true"
android:background="#color/grrenAcceptList"
android:minHeight="30dp"
android:minWidth="30dp"
android:visibility="gone">
<ImageView
android:id="#+id/imgAccept"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/aceptar"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="70dp"
android:layout_height="70dp"
android:minHeight="30dp"
android:minWidth="30dp"
android:background="#color/redD3"
android:id="#+id/lytUndo"
android:layout_alignParentRight="true"
android:visibility="gone">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgUndo"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="#drawable/undo"/>
</RelativeLayout>
</RelativeLayout>
You need to follow below Idea
1) this line of code mConverView = converView; doesn't makes sense. directly use converView(View from getView param). Remove mConvertView from the adapter.
2) Add some mechanism which can tell you which row is clicked and save that variable.
Example:- Have an boolean Array of size Rows.size . and set them in onClick.
Boolean[] array = new Boolean[getSize()];
in onClick that you already have in your getview set this.
public void onClick(View v) {
array[position] = !array[position];
viewHolder.lytUndo.setVisibility(View.VISIBLE);
//You do not need to call notifyDatasetChange.
3) in getView(), when you are setting data in to row items/or just before onClick. have a check like below.
if(array[position])// this will tell you if you need to show or hid lytUndo thing
viewHolder.lytUndo.setVisibility(View.VISIBLE); // Show it
else
viewHolder.lytUndo.setVisibility(View.GONE); // hide it or do whatever you want
You might need to set some params as final
I have written this as simple as possible, comment back with your result.

How to create a listView with multiple views in a row.

I am writing an app that requires the user to enter some details into a form. The form initially has 3 EditText views in a row. When the user enters some data in the last editText, the onFocusChangeListener should initiate a new row.
This is what I want to do.
How can I create 3 editText views in a single listView row at runtime?
To create a listView with multiple views in a row, you need to customize your adapter, so it can take the form of your row from a source XML -that you should create- and puts it into your listView, here is an example based on BaseAdapter:
This is your Xml source that contains the form of your Row:
espaceclientuploadsource.xml :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:addStatesFromChildren="true" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:addStatesFromChildren="true" >
<ImageView
android:id="#+id/Uplodimage"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="15dp"
android:src="#drawable/bingo" />
<TextView
android:id="#+id/UploadedProductName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="24dp"
android:layout_toRightOf="#+id/Uplodimage"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/UplodedProductPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/UploadedProductName"
android:layout_below="#+id/UploadedProductName"
android:layout_marginTop="16dp"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<ImageView
android:id="#+id/UploadedStatus"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_above="#+id/UplodedProductPrice"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/UploadedProductName"
android:layout_marginRight="27dp"
android:src="#drawable/bingo" />
<ImageView
android:id="#+id/ImageViewDelete"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_alignBottom="#+id/UplodedProductPrice"
android:layout_alignLeft="#+id/UploadedStatus"
android:clickable="true"
android:src="#drawable/bingo" />
</RelativeLayout>
Then you need to create an XML file that containes your ListView:
espaceclientuploads:
<EditText
android:id="#+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPassword" />
<Button
android:id="#+id/submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="submit"
android:text="Button" />
</LinearLayout>
Next is your adapter, it's role is to use your sourceXML as your row Format,
UploadedAdapter :
public class UploadedAdapter extends BaseAdapter
{
List<Article> lesArticles;
DataSource produitSource;
LayoutInflater inflater;
String path= Environment.getExternalStorageDirectory().toString()+File.separator+"Bingo";
public UploadedAdapter(Context context, List<Article> lesArticles)
{
inflater=LayoutInflater.from(context);
this.lesArticles = lesArticles;
}
#Override
public int getCount()
{
return lesArticles.size();
}
#Override
public Object getItem(int position)
{
return lesArticles.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
private class ViewHolder
{
TextView nomduProduit;
TextView prixDuProduit;
ImageView status;
ImageView imageDuProduit;
ImageView delete;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView==null)
{
holder=new ViewHolder();
convertView = inflater.inflate(R.layout.espaceclientuploadsource, null);
holder.nomduProduit = (TextView)convertView.findViewById(R.id.UploadedProductName);
holder.prixDuProduit = (TextView)convertView.findViewById(R.id.UplodedProductPrice);
holder.imageDuProduit = (ImageView)convertView.findViewById(R.id.Uplodimage);
holder.status = (ImageView)convertView.findViewById(R.id.UploadedStatus);
holder.delete=(ImageView)convertView.findViewById(R.id.ImageViewDelete);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
Drawable drawableImage = new BitmapDrawable(bitmapImage);
holder.imageDuProduit.setImageDrawable(drawableImage);
holder.nomduProduit.setText(lesArticles.get(position).getNomArticle());
holder.prixDuProduit.setText(lesArticles.get(position).getPrix());
holder.delete.setImageResource(R.drawable.delete);
return convertView;
}
}
As you can see, your adapter extends the baseAdapter which is an abstract class, so you need to Override its method.
Finally it's your activity that will display your listView:
public class EspaceClientUplodedProducts extends Activity{
List<Article> lesArticle= new ArrayList<Article>();
ListView lvListe;
UploadedAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.espaceclientuploads);
lvListe= (ListView)findViewById(R.id.UploadListView);
adapter = new UploadedAdapter(this, lesArticle);
lvListe.setAdapter(adapter);
lvListe.setOnItemClickListener(this);
}
}

Categories

Resources