GridView gets disoriented while scrolling - java

Items in the gridView sometimes overlap or move up or down a bit.But gets fixed when scrolling back up again.Unfortunately I can't provide an image because I am new here .I am not sure if i am doing something in code.But when use listView there is no problem.
Xml for the gridView:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.gametalks.MainActivity"
android:background="#color/card_white">
<GridView
android:columnWidth="10dp"
android:numColumns="2"
android:id="#+id/listView"
android:dividerHeight="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:verticalSpacing="30dp"
></GridView>
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
Here is the adapter:
[public class GameAdapter extends ArrayAdapter<GameNews> {
public GameAdapter(#NonNull Context context, List<GameNews> gameNews ){
super(context, 0, gameNews);
if(gameNews == null)
{
return;
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
GameNews currentNews = getItem(position);
// Check if the existing view is being reused, otherwise inflate the view
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.grid_item, parent, false);
final ViewHolder v = new ViewHolder();
// Find the TextView in the grid_item.xml layout with the ID version_name
v.Heading = (TextView) listItemView.findViewById(R.id.title);
v.description = (TextView) listItemView.findViewById(R.id.description);
v.newsImage = (ImageView) listItemView.findViewById(R.id.image) ;
v.source = (TextView) listItemView.findViewById(R.id.source);
v.time = (TextView) listItemView.findViewById(R.id.time);
v.menuButton = (Button) listItemView.findViewById(R.id.popup);
listItemView.setTag(v);
v.menuButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
PopupMenu popup = new PopupMenu(getContext(),view);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popup_menu, popup.getMenu());
popup.show();
}
});
}
ViewHolder viewHolder = (ViewHolder) listItemView.getTag();
//Setting title to current news title
viewHolder.Heading.setText(currentNews.getTitle());
viewHolder.description.setText(currentNews.getDescription());
viewHolder.newsImage.setTag(currentNews.getphotoUrl());
viewHolder.source.setText(currentNews.getSource());
viewHolder.time.setText(currentNews.getTime());
// Picasso.with(getContext()).load(currentNews.getphotoUrl()).into(viewHolder.newsImage);
if (URLUtil.isValidUrl(currentNews.getphotoUrl())) {
Picasso.with(getContext())
.load(currentNews.getphotoUrl())
.resize(350,300)
.tag(tag)
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(viewHolder.newsImage);
} else {
Picasso.with(getContext())
.load(R.drawable.right_line)
.resize(350,300)
.tag(tag)
.noPlaceholder()
.into(viewHolder.newsImage);
}
return listItemView;
}
public static class ViewHolder {
TextView Heading;
TextView description;
ImageView newsImage;
TextView source;
TextView time;
Button menuButton;
}
}][1]
If you need any other details please ask.

This happened due to the reason that i set the size of gridView items to wrap content and hence different items had different sizes.This caused unstability in the gridView.I fixed it by giving the items of the gridView a fixed dp size.And now it has no problem

Related

How To Add Checkboxes To ListView (Each list) in Android Studio

basically I am creating a Task/ToDo List app and I can't figure this part out. I want to add a checkbox next to each task and the ability to check them.
Here is the MainActivity.java
public class MainActivity extends AppCompatActivity {
static ArrayList<String> notes = new ArrayList<>();
static ArrayAdapter arrayAdapter;
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
if (item.getItemId() == R.id.add_note) {
Intent intent = new Intent(getApplicationContext(),
note_editor.class);
startActivity(intent);
return true;
}
return false;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView);
SharedPreferences sharedPreferences =
getApplicationContext().getSharedPreferences
("com.example.assignment1", Context.MODE_PRIVATE);
HashSet<String> set = (HashSet<String>)
sharedPreferences.getStringSet("notes", null);
if (set == null) {
notes.add("Add Your Task Hereee");
} else {
notes = new ArrayList(set);
}
arrayAdapter = new ArrayAdapter
(this, android.R.layout.simple_list_item_1, notes);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick
(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getApplicationContext(),
note_editor.class);
intent.putExtra("noteId", i);
startActivity(intent);
}
});
My main.xml
<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"
tools:context=".MainActivity">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:id="#+id/listView" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="32dp"
android:layout_marginBottom="28dp"
android:backgroundTint="#4BB3A9"
android:src="#drawable/add_task"/>
</RelativeLayout>
I want it to look something like this":
I drew the checkboxes here
I also have another class for when editing the tasks as well as for a splash screen but I don't think it's necessary here. Any help would be really appreciated!
You could use Recycler view instead of List view. See below code for Reference:
Create custom adapter and set it to your Recycler view and call it like recyclerView.setAdapter(CustomAdapter(new ArrayList("AAAAA","BBBBB","CCCCC","DDDDD"),getContext()));
Custom Adapter
public class CustomAdapter extends ArrayAdapter<String> {
private ArrayList<String> dataSet;
// View lookup cache
private static class ViewHolder {
CheckedTextView checkedTextView;
}
public CustomAdapter(ArrayList<String> data, Context context) {
super(context, R.layout.list_item, data);
this.dataSet = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.list_item, parent, false);
viewHolder.checkedTextView = convertView.findViewById(R.id.check_box);
viewHolder.checkedTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
viewHolder.checkedTextView.setChecked(!viewHolder.checkedTextView.isChecked());
}
});
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.checkedTextView.setText(dataSet.get(position));
return convertView;
}
}
XML code for each list item : list_item.xml
<CheckedTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/check_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:checked="false"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:gravity="center"
android:text="Check Me"
/>
You are using an android default layout for your ListView and this default layout shows a TextView only, you have to create custom layout for your list item views and custom ArrayAdapter to achieve what you want.
for more information check out this:https://javapapers.com/android/android-listview-custom-layout-tutorial/
As a tip switch for RecyclerView which is much more efficient: https://developer.android.com/guide/topics/ui/layout/recyclerview

Adding a check box (only one can be checked at a time) to my custom list view

I have made my custom adapter and am adapting an array of "persons". In my list item xml i have put a checkbox, but this is where i get confused. I want my list to only be able to have one check box checked at a time. And i also want to implement an OnCheckBox click listener of some sort to preform an action each time a different check box is selected.
this is my custom adapter
public class PersonAdapter extends BaseAdapter {
Context mContext;
Person[] mPersonArray;
public PersonAdapter(Context context , Person[] persons) {
mContext = context;
mPersonArray = persons;
}
#Override
public int getCount() {
return mPersonArray.length;
}
#Override
public Object getItem(int position) {
return mPersonArray[position];
}
#Override
public long getItemId(int position) {
return 0; // we wont use
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
// brand new
convertView = LayoutInflater.from(mContext).inflate(R.layout.person_list_item , null);
holder = new ViewHolder();
holder.nameText = (TextView) convertView.findViewById(R.id.nameTextView);
holder.birthDateText = (TextView) convertView.findViewById(R.id.birthDateTextView);
holder.checkBoxList = (CheckBox) convertView.findViewById(R.id.checkBox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Person personForList = mPersonArray[position];
holder.nameText.setText(personForList.getName());
holder.birthDateText.setText(personForList.getBirthDate());
return convertView;
}
public static class ViewHolder {
TextView nameText;
TextView birthDateText;
CheckBox checkBoxList;
}
Here is my list item xml
<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="wrap_content"
tools:background="#ff53">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Evan Dix"
android:id="#+id/nameTextView"
android:textColor="#ff323232"
android:textSize="30sp"
android:layout_marginLeft="50dp"
android:layout_marginStart="86dp"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="11-12-12"
android:id="#+id/birthDateTextView"
android:textColor="#ff323232"
android:layout_marginStart="23dp"
android:layout_centerVertical="true"
android:layout_toEndOf="#+id/imageView"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView"
android:src="#android:drawable/presence_invisible"
android:layout_centerVertical="true"
android:layout_toEndOf="#+id/nameTextView"
android:layout_marginStart="12dp"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/checkBox"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_marginEnd="29dp"
android:checked="false"
android:clickable="true"
android:choiceMode = "singleChoice"/>
And inside my class where i am populating the listview.... it extends ListAdapter
Person[] personArray = new Person[mPersonArrayList.size()];
personArray = mPersonArrayList.toArray(personArray);
PersonAdapter adapter = new PersonAdapter(this , personArray);
setListAdapter(adapter);
I had used this in my project and you can also try, but if you have to check one checkbox at one time then why are you using checkbox you have to use radiobutton.
// initialize selectPosition in your base adapter
int selectedPosition = -1;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
// brand new
convertView = LayoutInflater.from(mContext).inflate(R.layout.person_list_item , null);
holder = new ViewHolder();
holder.nameText = (TextView) convertView.findViewById(R.id.nameTextView);
holder.birthDateText = (TextView) convertView.findViewById(R.id.birthDateTextView);
holder.checkBoxList = (CheckBox) convertView.findViewById(R.id.checkBox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Person personForList = mPersonArray[position];
holder.nameText.setText(personForList.getName());
holder.birthDateText.setText(personForList.getBirthDate());
holder.checkBoxList.setChecked(position == selectedPosition);
holder.checkBoxList.setTag(position);
holder.checkBoxList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
selectedPosition = (Integer) view.getTag();
notifyDataSetInvalidated();
notifyDataSetChanged();
}
});
return convertView;
}
It sounds like what your are looking for is a radio button rather than a check box.
Check boxes are made so that you are able to select multiple items of one category, where radio buttons are made so that you are able to only click one of the category.

listview data not shows in fragment

I have a fragment FragmentTab1 & I want to replace AllContactsFragment fragment which consists a listview & two button. The replacement performs well, but data is not showing in ListView. Data shows in log cat as well.
The replacement code Inside FragmentTab1 is:
AllContactsFragment allContactsFragment = new AllContactsFragment();
FragmentTransaction transaction = getFragmentManager()
.beginTransaction();
transaction.addToBackStack(null);
transaction.add(R.id.fragmentTabLayout1, allContactsFragment);
transaction.commit();
I fill up data in listview inside AllContactsFragment like:
public class AllContactsFragment extends SherlockFragment implements
OnClickListener {
ListView listViewAllContact;
Button btnAdd, btnCacel;
List<BlockNumber> contactNumberlist;
View rootView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_all_contacts, container,
false);
// data are comes well & checked in Log cat
contactNumberlist = PhoneUtils.getAllContacts(getActivity());
listViewAllContact = (ListView) rootView
.findViewById(R.id.listViewAllContact);
ContactListAdapter adapter = new ContactListAdapter(getActivity(),
contactNumberlist, m_onSelectedEventCalender);
listViewAllContact.setAdapter(adapter);
if (container == null) {
return null;
}
return rootView;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onClick(View v) {
}
}
I also share my ContactListAdapter adapter
public class ContactListAdapter extends BaseAdapter {
private List<BlockNumber> allContactsNumbers = null;
public Context context;
public LayoutInflater inflater;
private ViewHolder holder;
private onSelectedEventCalender m_onSelectedEventCalender;
public ContactListAdapter(Context context, List<BlockNumber> allNumberList,
onSelectedEventCalender m_onSelectedEventCalender) {
super();
this.context = context;
this.allContactsNumbers = allNumberList;
this.inflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.m_onSelectedEventCalender = m_onSelectedEventCalender;
}
#Override
public int getCount() {
return allContactsNumbers.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
try {
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.list_row, null);
convertView.setMinimumHeight(50);
holder.textViewContactName = (TextView) convertView
.findViewById(R.id.textview_contact_name);
holder.textView_Contact_Number = (TextView) convertView
.findViewById(R.id.textview_number);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
holder.textViewContactName.setText(allContactsNumbers.get(
position).getName());
holder.textView_Contact_Number.setText(allContactsNumbers.get(
position).getNumber());
holder.textViewContactName.setTag(allContactsNumbers
.get(position));
return convertView;
}
} catch (Exception ex) {
Log.w("Exception", ex.getMessage());
}
return null;
}
public static class ViewHolder {
TextView textViewContactName;
TextView textView_Contact_Number;
// TextView textViewEventEndDate;
}
public interface onSelectedEventCalender {
void onSelectedEventCalender(BlockNumber aBlockNumber, int type);
}
}
Corresponding XML for AllContactsFragment is fragment_all_contacts.xml :
<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:background="#drawable/bg_new" >
<!-- android:background="#80000000" -->
<RelativeLayout
android:id="#+id/relativeLayoutFragmentMain"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ListView
android:id="#+id/listViewAllContact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/imageViewLine1" >
</ListView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dip"
android:layout_alignParentBottom="true"
android:background="#drawable/action_bar"
android:gravity="center_vertical"
android:orientation="horizontal" >
<Button
android:id="#+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dip"
android:layout_weight="1"
android:text="Add" />
<Button
android:id="#+id/btnCanel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="8dip"
android:layout_weight="1"
android:text="Home" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
May be I am missing something?
Edited: to make above code right.
remove android:layout_below="#+id/imageViewLine1" from ListView definition XML , remove return null from getView() in adapter & check the data is available or not which is set to listview.
i would try
1) in xml set your listview "above" your linear-layout-button-bar
2) after creating ContactListAdapter adapter call adapter.notifyDataSetChanged()
3) in the adapter in the first if - after convertView.setTag(holder); set return convertView;
4) create and set the adapter in the onViewCreated() Method
or
replace your listview once with an imageview and look if you will see the image, than you know for sure that the listview is the one that fails (don't forget to set a background!)
Woh! What a foolish I am? My contactNumberlist is empty because I don't add the object in the list. My Log cat misleading me. Thanks for #Ragunandan & #tom nobleman for their great afford to find mistakes.
My ContactListAdapter getView() looks like :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.list_row, null);
convertView.setMinimumHeight(50);
holder.textViewContactName = (TextView) convertView
.findViewById(R.id.textview_contact_name);
holder.textView_Contact_Number = (TextView) convertView
.findViewById(R.id.textview_number);
holder.imgViewContactImage = (ImageView) convertView
.findViewById(R.id.imgViewContactImage);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
if (allContactsNumbers.size() <= 0) {
holder.textViewContactName.setText("No Data");
} else {
holder = (ViewHolder) convertView.getTag();
String name = allContactsNumbers.get(position).getName();
holder.textViewContactName.setText(name);
String number = allContactsNumbers.get(position).getNumber();
holder.textView_Contact_Number.setText(number);
Uri Uri = allContactsNumbers.get(position).getImage_Uri();
if (Uri != null) {
holder.imgViewContactImage.setImageURI(Uri);
} else {
holder.imgViewContactImage.setImageResource(R.drawable.ic_no_image);
}
Log.d("Contacts in Adapter", "" + name + "" + number);
}
return convertView;
}

Toast when checked in custom adapter listview

I want when I checked on check box the code returns string of text view that's in the same row only.
I'm using LayoutInflater and another class which has code for creating list containing strings.
My code :
public class InteractiveArrayAdapter extends ArrayAdapter<model> {
private final List<model> list;
private final Activity context;
public InteractiveArrayAdapter(Activity context, List<model> list) {
super(context, R.layout.rep, list);
this.context = context;
this.list = list;
}
static class ViewHolder {
protected TextView text;
protected CheckBox checkbox;
}
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.rep, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) view.findViewById(R.id.TextView07);
viewHolder.checkbox = (CheckBox) view.findViewById(R.id.CheckBox05);
viewHolder.checkbox
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
model element = (model) viewHolder.checkbox
.getTag();
element.setSelected(buttonView.isChecked());
}
});
view.setTag(viewHolder);
viewHolder.checkbox.setTag(list.get(position));
} else {
view = convertView;
((ViewHolder) view.getTag()).checkbox.setTag(list.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.text.setText(list.get(position).getName());
holder.checkbox.setChecked(list.get(position).isSelected());
return view;
}
}
my xml :
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TableLayout
android:id="#+id/h103"
android:layout_width="match_parent"
android:layout_height="27dp"
android:layout_x="0dp"
android:layout_y="0dp"
android:background="#drawable/back1" >
<TableRow
android:id="#+id/TableRow05"
android:layout_width="match_parent"
android:layout_height="27dp"
android:layout_marginTop="4dp" >
<CheckBox
android:id="#+id/CheckBox05"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="-4dp"
android:button="#drawable/test" />
<TextView
android:id="#+id/TextView07"
android:layout_width="220dp"
android:layout_height="22dp"
android:layout_marginLeft="23dp"
android:layout_marginTop="-6dp"
android:text="" />
<TextView
android:id="#+id/TextView08"
android:layout_width="110dp"
android:layout_height="22dp"
android:layout_marginLeft="0dp"
android:layout_marginTop="-4dp"
android:text="095110263" />
</TableRow>
</TableLayout>
</AbsoluteLayout>
You have to work on checkbox.onclicklistener rather then checkbox.onCheckedChanged because if you uses it in list view then it will automatically called then your checked check box will hide out.
new OnClickListener()
{
#Override
public void onClick(View view)
{}
}
in onclicklistener, you get view as parameter which is a check box. here view has a method of getparent() which returns you a view in which your check box is set. you can check it by printing in log. if u got parent of check box then u can also get all child views of parent in which 1 child view is check box. from all child views u can get there values to show them in toast. if check box's parent has another parent in view of list item then u can also get parent of parent view by calling a getparent() method.
Please keep in mind that views have parent child relation so if you wants all child then you have to get parent.
First Add 1 button at bottom of ur list view btnOk
btnOk.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
StringBuffer responseText = new StringBuffer();
ArrayList<model> almodel = adapter.almodel;
responseText.append("The following were selected...\n");
for(int i=0;i<almodel.size();i++)
{
model m = almodel.get(i);
if(m.isSelected())
{
responseText.append("\n" + m.getName());
}
}
Toast.makeText(getApplicationContext(),responseText,Toast.LENGTH_LONG).show();

How to use setEmptyView() with custom list layout in ListFragment

I'm using a paginator with a few Fragments.
I want to show a message when there are no entries in the list (Fragment).
I tried to use Textview with android:id="#id/android:empty but it doesn't work.
Custom list 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:padding="#dimen/padding_medium" >
<TextView
android:id="#+id/label_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="#dimen/padding_medium"
android:text="#string/label_value"
android:textColor="#android:color/white"
android:textSize="18sp" />
<TextView
android:id="#+id/label_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="#dimen/padding_medium"
android:text="#string/title_time"
android:textColor="#android:color/white"
android:textSize="16sp" />
</RelativeLayout>
List adapter class:
public class JournalAdapter extends ArrayAdapter<String> {
private final Context context;
private final List<String> values;
private final List<String> dates;
public JournalAdapter(Context context, List<String> values,
List<String> dates) {
super(context, R.layout.layout_journal_list, values);
this.context = context;
this.values = values;
this.dates = dates;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.layout_journal_list, parent, false);
TextView value = (TextView) rowView.findViewById(R.id.label_glucose);
TextView date = (TextView) rowView.findViewById(R.id.label_date);
value.setText(values.get(position));
date.setText(dates.get(position));
return rowView;
}
}
List parsing method:
private void initListView() {
values = dataSource.getAllValues();
List<String> values = new ArrayList<String>();
List<String> dates = new ArrayList<String>();
for (Value value : values) {
values.add(Double.toString(value.getValue()));
dates.add(secondsToDate(value.getDate()));
}
setListAdapter(new JournalAdapter(context, values, dates));
listView = getListView();
listView.setEmptyView(noItems("NO ITEMS"));
listView.setOnItemClickListener(this);
}
noItems method:
private TextView noItems(String text) {
TextView emptyView = new TextView(context);
emptyView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
emptyView.setText(text);
emptyView.setTextColor(Color.WHITE);
emptyView.setTextSize(20);
emptyView.setVisibility(View.GONE);
emptyView.setGravity(Gravity.CENTER_VERTICAL
| Gravity.CENTER_HORIZONTAL);
return emptyView;
}
This worked for me (got the solution from this question asked by William Remacle). What you might have missed is adding the created TextView to the ListView layout parent (second line of code from the bottom of the noItems method below):
In my ListFragment I used the following method to get a view for the empty view:
private TextView noItems(String text) {
TextView emptyView = new TextView(getActivity());
//Make sure you import android.widget.LinearLayout.LayoutParams;
emptyView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
//Instead of passing resource id here I passed resolved color
//That is, getResources().getColor((R.color.gray_dark))
emptyView.setTextColor(getResources().getColor(R.color.gray_dark));
emptyView.setText(text);
emptyView.setTextSize(12);
emptyView.setVisibility(View.GONE);
emptyView.setGravity(Gravity.CENTER_VERTICAL
| Gravity.CENTER_HORIZONTAL);
//Add the view to the list view. This might be what you are missing
((ViewGroup) getListView().getParent()).addView(emptyView);
return emptyView;
}
Then in the onStart() method of the the ListFragment set the the empty view:
#Override
public void onStart() {
super.onStart();
getListView().setEmptyView(
noItems(getResources().getString(R.string.widget_empty)));
}
android:id="#android:id/empty"
and not
android:id="#id/android:empty"

Categories

Resources