I got a list, that i would like to show in a ListView, using my own custom adapter. So this list have some null values in it, and also some "important" not-null values.
It could be like this:
(N representing Null)
(D representint some valuable data)
myList:
[N,N,D,D,N,N,D,N,D,N,N] for example.
So i got my adapter, but i cannot handle the null values in the list.
This is my adapter:
public class ItemAdapter extends ArrayAdapter {
List<Item> itemList;
private Activity act;
boolean selling;
public ItemAdapter(Activity act, List<Item> itemList, boolean selling) {
super(act, R.layout.item_view_layout, itemList);
this.itemList = itemList;
this.act = act;
this.selling = selling;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
final Item itemManipulated = itemList.get(position);
if (convertView == null) {
convertView = new ItemInShopView(act, itemManipulated);
holder = new ViewHolder();
holder.convertView = convertView;
holder.itemNameTextView = (TextView) ((ItemView) convertView).getItemNameTextView();
holder.iconImageView = (ImageView) ((ItemView) convertView).getItemIconImageView();
holder.coinView = (CoinView) ((ItemInShopView) convertView).getCoinView();
holder.coinView.init(act);
holder.itemRarityHidedTextView = (TextView) ((ItemView) convertView).getItemRarityHidedTextView();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.itemNameTextView.setText(itemManipulated.getName());
holder.iconImageView.setImageResource(itemManipulated.getIcon());
holder.itemRarityHidedTextView.setText(itemManipulated.getRarity());
Colorer.setTextViewColorByItemRarity(holder.itemNameTextView, holder.getRarity(), act);
if (selling) {
holder.coinView.setCoins(itemManipulated.getSellPrice());
} else {
holder.coinView.setCoins(itemManipulated.getPrice());
}
holder.convertView.setOnClickListener(new OnClickListenerWithPreventDoubleTapper(itemManipulated));
holder.convertView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
return false;
}
});
return convertView;
}
class OnClickListenerWithPreventDoubleTapper extends OnClickListenerWithPreventDoubleTap {
Item item;
public OnClickListenerWithPreventDoubleTapper(Item item) {
this.item = item;
}
#Override
protected void performAction() {
new ItemDialog(act, item).show();
}
}
static class ViewHolder {
TextView itemRarityHidedTextView;
TextView itemNameTextView;
ImageView iconImageView;
CoinView coinView;
View convertView;
public String getRarity() {
return itemRarityHidedTextView.getText().toString();
}
}
}
How could i implement some way to get the adapter handle null values and shows nothing there, or maybe show a dummy layout with nothing on it?
I couldnt make a new list without null values and pass these new list to the adapter, because the nulls have an important meaning in an other view.
I hope my problem is clear. Please help if you can.
Why not just?
if (itemManipulated != null){
holder.itemNameTextView.setText(itemManipulated.getName());
holder.iconImageView.setImageResource(itemManipulated.getIcon());
holder.itemRarityHidedTextView.setText(itemManipulated.getRarity());
Colorer.setTextViewColorByItemRarity(holder.itemNameTextView, holder.getRarity(),act);
if (selling) {
holder.coinView.setCoins(itemManipulated.getSellPrice());
} else {
holder.coinView.setCoins(itemManipulated.getPrice());
}
} else {
holder.itemNameTextView.setText("No Item");
... (whatever default values you like)
}
Edit:
If you don't want to display nulls at all you will need to do something more complex.
in getView: find the nth piece of actual data
in getCount: return the number of pieces of actual data
getView:
int posInArray = -1;
for (int i =0; i <= position; i++){
posInArray++;
while(itemList.get(posInArray) == null){
posInArray++;
}
}
itemManipulated = itemList.get(posInArray);
...
getCount:
int count = 0;
for(int i = 0; i < itemList.size(); i++){
if (itemList.get(i) != null){
count++;
}
}
return count;
Related
I'm using Realm in my mobile application to store line items for my list view. I'm extending the RealmBaseAdapter which is working fine. Problem is that if I make a query to the database to filter my items, my adapter is not picking up the changed list and causing the out of bound index error.
This is where I set my adapter with the initial values,
results = realm.where(BillingLineItem.class).findAll();
adapter = new BillingListAdapter(getActivity(), results);
And this is the part that I'm doing the filtering based on the spec number,
results = realm.where(BillingLineItem.class)
.equalTo("SpecNumber", spec)
.findAll();
adapter.notifyDataSetChanged();
And like I said before After that query results will be updated but adapter doesn't pick up the changes.
EDIT: My adapter for the list view
public class BillingListAdapter extends RealmBaseAdapter<BillingLineItem> {
private LayoutInflater inflater = null;
private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();
private boolean isActionMode;
public BillingListAdapter(Context mContext, RealmResults<BillingLineItem> lineItems) {
super(mContext,lineItems);
inflater = (LayoutInflater) mContext.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.isActionMode = false;
}
// I commented out this part because RealmBaseAdapter automaticly implements this methods in the super class
/*#Override
public int getCount() {
return lineItems.size();
}
#Override
public Object getItem(int position) {
return lineItems.get(position);
}
#Override
public long getItemId(int position) {
return position;
}*/
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder;
if (convertView == null) {
/****** Inflate billing_foreground_item.xml file for each row ( Defined below ) *******/
vi = inflater.inflate(R.layout.billing_foreground_item, null);
/****** View Holder Object to contain billing_foreground_item.xml file elements ******/
holder = new ViewHolder();
holder.SubOper = (TextView) vi.findViewById(R.id.tvSubOper);
holder.Spec = (TextView) vi.findViewById(R.id.tvSpec);
holder.Address = (TextView) vi.findViewById(R.id.tvAddress);
holder.SKU = (TextView) vi.findViewById(R.id.tvSku);
holder.SKUDesc = (TextView) vi.findViewById(R.id.tvSkuDesc);
holder.Quantity = (TextView) vi.findViewById(R.id.tvQuantity);
holder.Unit = (TextView) vi.findViewById(R.id.tvUnit);
holder.BilledQty = (TextView) vi.findViewById(R.id.tvBBilledQty);
holder.RemainingQty = (TextView) vi.findViewById(R.id.tvRemainingQty);
holder.ivLineIcon = (ImageView) vi.findViewById(R.id.ivLineIcon);
holder.rlItem = (RelativeLayout) vi.findViewById(R.id.rlItem);
holder.ErrorMessage = (TextView) vi.findViewById(R.id.txtErrorDisplay);
/************ Set holder with LayoutInflater ************/
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
/************ Set Model values in Holder elements ***********/
if (adapterData.get(position).getFinalFlag()) {
holder.ivLineIcon.setImageResource(R.drawable.finalflagblue);
holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 255));
if (adapterData.get(position).getCompleted()) {
holder.rlItem.setBackgroundColor(Color.rgb(223, 235, 245));
}
if (adapterData.get(position).getErrorFlag()){
holder.rlItem.setBackgroundColor(Color.rgb(231, 25, 57));
holder.ErrorMessage.setVisibility(View.VISIBLE);
holder.ErrorMessage.setText(adapterData.get(position).getErrorMessage());
}
} else if (adapterData.get(position).getDeleteFlag()) {
holder.ivLineIcon.setImageResource(R.drawable.trashiconred);
holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 255));
if (adapterData.get(position).getErrorFlag()){
holder.rlItem.setBackgroundColor(Color.rgb(231, 25, 57));
holder.ErrorMessage.setVisibility(View.VISIBLE);
holder.ErrorMessage.setText(adapterData.get(position).getErrorMessage());
}
} else if (adapterData.get(position).getChanged()) {
holder.ivLineIcon.setImageResource(R.drawable.changedicongreen);
holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 255));
if (adapterData.get(position).getErrorFlag()){
holder.rlItem.setBackgroundColor(Color.rgb(231, 25, 57));
holder.ErrorMessage.setVisibility(View.VISIBLE);
holder.ErrorMessage.setText(adapterData.get(position).getErrorMessage());
}
} else if (adapterData.get(position).getNewLine()) {
holder.ivLineIcon.setImageResource(R.drawable.newlineicon);
holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 255));
if (adapterData.get(position).getErrorFlag()){
holder.rlItem.setBackgroundColor(Color.rgb(231, 25, 57));
holder.ErrorMessage.setVisibility(View.VISIBLE);
holder.ErrorMessage.setText(adapterData.get(position).getErrorMessage());
}
} else {
holder.ivLineIcon.setImageResource(R.drawable.linesiconblack);
holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 255));
holder.ErrorMessage.setVisibility(View.GONE);
}
if (mSelection.get(position) != null) {
//Log.d(TAG, "Item Selected");
holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 192));// this is a selected position so make it hilighted
}
holder.SubOper.setText(adapterData.get(position).getSubOper());
holder.Spec.setText(adapterData.get(position).getSpecNumber());
holder.Address.setText(adapterData.get(position).getAddress());
holder.SKU.setText(adapterData.get(position).getSKUNumber());
holder.SKUDesc.setText(adapterData.get(position).getSKUDesc());
holder.Quantity.setText(adapterData.get(position).getQuantity());
holder.Unit.setText(adapterData.get(position).getUnit());
holder.BilledQty.setText(adapterData.get(position).getBilledQty());
holder.RemainingQty.setText(adapterData.get(position).getRemainingQty());
return vi;
}
public void setNewSelection(int position, boolean value) {
mSelection.put(position, value);
notifyDataSetChanged();
}
public boolean isPositionChecked(int position) {
Boolean result = mSelection.get(position);
return result == null ? false : result;
}
public Set<Integer> getCurrentCheckedPosition() {
return mSelection.keySet();
}
public void removeSelection(int position) {
mSelection.remove(position);
notifyDataSetChanged();
}
public void clearSelection() {
mSelection = new HashMap<Integer, Boolean>();
notifyDataSetChanged();
}
public void setActionMode(boolean isActionMode)
{
this.isActionMode = isActionMode;
}
#Override
public boolean isEnabled(int position)
{
final BillingLineItem item = (BillingLineItem) getItem(position);
if (!item.getDeleteFlag().equals("true"))
{
//only enable items that are not inside the basket
return true;
}
//all other items are disabled during actionmode
return false;
}
public static class ViewHolder {
public TextView SubOper;
public TextView Spec;
public TextView Address;
public TextView SKU;
public TextView SKUDesc;
public TextView Quantity;
public TextView Unit;
public TextView BilledQty;
public TextView RemainingQty;
public ImageView ivLineIcon;
public RelativeLayout rlItem;
public TextView ErrorMessage;
}
}
Some information to point out here:
Android is based on java thus it's variables are passed by reference value (More Info).
It means that if you have an object:
RealmResults<BillingLineItem> results;
And you pass this variable as a parameter to the Adapter constructor:
adapter = new BillingListAdapter(getActivity(), results);
The list which you have outside the adapter and the variable inside the adapter are actually the same objects (two variables pointing to the same reference).
After you make your second query:
results = realm.where(BillingLineItem.class)
.equalTo("SpecNumber", spec)
.findAll();
You are making a new reference and storing it in the result object thus the list outside the adapter and the list which you passed earlier to the adapter are literally different objects so the adapter will not be able to sense the change and you get the error. You can fix it like this:
results.clear();
//adapter.notifyDataSetChanged() if you want to show the change before data fetched...
results.addAll(realm.where(BillingLineItem.class)
.equalTo("SpecNumber", spec)
.findAll());
adapter.notifyDataSetChanged();
I want to check whether the particular row of data is present or not in database. If data is present then set visibility mode is visible and display my first image if data is not present in database then set visibility is Invisible and display my second image.
Here is my code.
public class ListViewAdapter extends BaseAdapter {
Context context;
LayoutInflater inflater;
ArrayList<Product> AllMenu = new ArrayList<>();
ImageLoader imageLoader;
SQLiteDatabase sqLite;
public ListViewAdapter(Context context, ArrayList<Product> itemlist) {
this.context=context;
AllMenu = itemlist;
imageLoader = new ImageLoader(context);
}
public int getCount() {
return AllMenu.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public View getView(final int position, final View convertView, ViewGroup parent) {
// Declare Variables
Product tempMenu = AllMenu.get(position);
ImageView image_path,facility1,facility_1;
TextView name,location,desc,facility2,facility3,facility4;
ListView listView;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View view = inflater.inflate(R.layout.viewpage, parent, false);
// Get the position
//listView = (ListView) view.findViewById(R.id.myimagelist);
name = (TextView) view.findViewById(R.id.fh_name);
location = (TextView) view.findViewById(R.id.fh_loc);
desc = (TextView) view.findViewById(R.id.fh_desc);
facility1 = (ImageView) view.findViewById(R.id.fh_fc1);
facility_1 = (ImageView) view.findViewById(R.id.fh_fc11);
image_path = (ImageView) view.findViewById(R.id.image_all_main);
name.setText(tempMenu.getName());
location.setText(tempMenu.getLocation());
desc.setText(tempMenu.getDescription());
for(Product myPoint : AllMenu) {
if(myPoint.getFacility1() != null && myPoint.getFacility1().contains("Pool")) {
facility1.setVisibility(view.VISIBLE);
facility_1.setVisibility(view.INVISIBLE);
}else {
facility_1.setVisibility(view.VISIBLE);
facility1.setVisibility(view.INVISIBLE);
}
}
imageLoader.DisplayImage(tempMenu.getImage_path(),image_path);
return view;
}}
All data should come from server. Please help me solve this problem. Thank You
I want to compare with my string here is "Pool" is my string in above code.
If given string == pool then set Visibile or else set Invisible.
I want to make my changes here only.
for(Product myPoint : AllMenu) {
if(myPoint.getFacility1() != null && myPoint.getFacility1().contains("Pool")) {
facility1.setVisibility(view.VISIBLE);
facility_1.setVisibility(view.INVISIBLE);
}else {
facility_1.setVisibility(view.VISIBLE);
facility1.setVisibility(view.INVISIBLE);
}
}
Use log in your code to make sure that your comparing code working and also use equalsIgnoreCase like #shark says. Like this:
for(Product myPoint : AllMenu) {
Log.d("LIST_VIEW_ADAPTER", myPoint.getFacility1());
if(myPoint.getFacility1() != null && myPoint.getFacility1().equalsIgnoreCase("Pool")) {
facility1.setVisibility(view.VISIBLE);
facility_1.setVisibility(view.INVISIBLE);
Log.d("LIST_VIEW_ADAPTER", "facility1 contains Pool");
}else {
facility_1.setVisibility(view.VISIBLE);
facility1.setVisibility(view.INVISIBLE);
Log.d("LIST_VIEW_ADAPTER", "facility1 no Pool!");
}
}
Check log result in android monitor and make sure that it always return "facility1 contains Pool" for the right set visibility.
I prefer to split checking 'null' value in it's own if, like this:
for(Product myPoint : AllMenu) {
Log.d("LIST_VIEW_ADAPTER", myPoint.getFacility1());
if(myPoint.getFacility1() != null) {
if(myPoint.getFacility1().equalsIgnoreCase("Pool")) {
facility1.setVisibility(view.VISIBLE);
facility_1.setVisibility(view.INVISIBLE);
Log.d("LIST_VIEW_ADAPTER", "facility1 contains Pool");
} else {
facility_1.setVisibility(view.VISIBLE);
facility1.setVisibility(view.INVISIBLE);
Log.d("LIST_VIEW_ADAPTER", "facility1 no Pool!");
}
} else {
// do something if null here.
Log.d("LIST_VIEW_ADAPTER", "NULL Value!");
}
}
-- UPDATE --
You should return position value in your following code:
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
To :
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
I have a custom adapter MyAdapter which displays items from a dynamic list(list2).. The list shows Area, location and there corresponding total items. there can be n number of similar area and location. I want to show a row "subtotal" which adds the corresponding total items of Similar Areas. Till now I'm able to show sorted items and "Total" items at end.
Now I want to display "subTotal" row after items of similar Area.
I don't know how do I compare each row till I get different Areas, in my Custom Adapter. Here's the code for my Adapter:
private class MyAdapter extends BaseAdapter {
private LayoutInflater inflater = null;
private ViewHolder holder = null;
#Override
public int getCount() {
// TODO Auto-generated method stub
if (!list2.isEmpty())
return list2.size();
else
return countItems.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
if (!list2.isEmpty())
return list2.get(position);
else
return countItems.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(final int position, View convertView,
final ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView == null) {
holder = new ViewHolder();
inflater = (LayoutInflater) mActivity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(
R.layout.activity_search_group_row, null);
holder.text_area = (TextView) convertView
.findViewById(R.id.edtTxtRef);
holder.text_loc = (TextView) convertView
.findViewById(R.id.edtTxtName);
holder.text_total = (TextView) convertView
.findViewById(R.id.edtTxtPrice);
holder.total_lly = (LinearLayout) convertView
.findViewById(R.id.total_lly);
holder.txtSubTotal = (TextView) convertView
.findViewById(R.id.txtSubTotal);
holder.txtCount = (TextView) convertView
.findViewById(R.id.txtCount);
holder.txtCountTotal = (TextView) convertView
.findViewById(R.id.txtCountTotal);
holder.sum_lly = (LinearLayout) convertView
.findViewById(R.id.sum_lly);
holder.top_lly = (LinearLayout) convertView
.findViewById(R.id.top_lly);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
System.out.println("=====*********adapter*********======");
int total1 = 0;
if (!locList.isEmpty() && !areaList.isEmpty()) {
if (!list2.isEmpty()) {
if (list2.size() - 1 == position) {
for (int k = 0; k < countItems.size(); k++) {
total1 = total1 + countItems.get(k);
}
lastRow = true;
}
}
holder.text_area.setText(list2.get(position).getArea());
holder.text_loc.setText(list2.get(position).getLocation());
holder.text_total.setText(String.valueOf(countItems.get(position)));
} else {
searchList.setDivider(new ColorDrawable(
android.R.color.transparent));
searchList.setDividerHeight(0);
// when area and location spinners are null
if (locList.isEmpty() && areaList.isEmpty()) {
if (countItems.size() - 1 == position) {
for (int k = 0; k < countItems.size(); k++) {
total1 = total1 + countItems.get(k);
}
lastRow = true;
}
holder.top_lly.setVisibility(View.GONE);
}
}
if (lastRow) {
holder.sum_lly.setVisibility(View.VISIBLE);
holder.txtCountTotal.setText(String.valueOf(total1));
holder.txtCountTotal.setVisibility(View.VISIBLE);
lastRow = false;
}
return convertView;
}
private class ViewHolder {
TextView text_area, text_loc, text_total, txtSubTotal, txtCount,
txtCountTotal;
LinearLayout total_lly, sum_lly, top_lly;
}
}
You can have a POJO with attributes like area, location, and total. Then create a map of <String,List<YourPojo>> and populate it with area as the key and the List of POJO as value. Here you will get the values separated by area.
As an example, it will look like:
area1 -> [{area1,loc1,20},{area1,loc2,10}]
area2 -> [{area2,loc1,1},{area2,loc2,10}]
and so on.
In this way you will get different Lists for different keys.
Then iterate the keySet of the map and for every key show the value in different table rows.
Once display of one key is complete, create a row for subtotal for that particular key and then continue with the next key.
I hope this helps!
You must sort your list by a custom comparator!
http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html
Create a class and implement the Comparator-Interface. Then you can define your own sorting-rules.
public class MyComparator implements Comparator<MyListObjectType> {
#Override
public int compare(MyListObjectType o1, MyListObjectType o2) {
if (o1.getTotal() > o2.getTotal()) {
return 1;
}
if (o1.getTotal() < o2.getTotal()) {
return -1;
}
if (o1.getTotal() == o2.getTotal()) {
return 0;
}
}
}
Use the comparator with:
Collections.sort( list, new MyComparator() );
An alternative is the implementation of the comparable-interface for your objects in your list.
You must have a list which contain unique Model object based on area and location so you must override equal and hashcode method
let it is your model
class Model {
String area;
String location;
int count;
Model(String area,String location) {
this.area = area;
this.location = location;
}
public String getLocation() {
return location;
}
public String getArea() {
return area;
}
#Override
public boolean equals(Object o) {
if (o == this) {
count = 1;
return true;
} else if (o instanceof Model) {
Model t = (Model) o;
if (t.getArea().equalsIgnoreCase(getArea()) && t.getLocation().equalsIgnoreCase(getLocation())) {
count++;
return true;
}
}
return false;
}
public int getCount() {
return count;
}
#Override
public int hashCode() {
return super.hashCode();
}
}
For Example modelList hold the data
use list to show data it will hold unique data based on area and location and also have total count pass it to adapter
ArrayList<Model> model = new ArrayList(); //you have all data with same area and location
ArrayList<Model> list = new ArrayList(); //it will hold total area with same area + location
for(int i=0;i<model.size()-1;i++){
Model t = model.get(i);
for(int j=i+1;j<model.size();j++){
Model m = model.get(j);
if(!t.equals(m)){
list.add(t);
}else{
if(!list.contains(t)){
list.add(t);
}
}
}
}
I'm using ListView to show search results. I have a Coustomized arrayListAdapter which returns a list of Objects. This is working fine. My listView is showing just a TextView nothing else.
But I want to clear the List when I again go to the search page. I have tried
#Override
protected void onResume()
{
mListAdapter.clear();
mListAdapter.notifyDataSetChanged();
super.onResume();
}
And the SearchListAdapter
public class SearchListAdapter extends ArrayAdapter<Chapter>
{
public Context context;
private static String searchText = null;
public SearchListAdapter(Context context)
{
super(context, R.layout.favorite_tab_list_view_row);
this.context = context;
}
#Override
public void clear()
{
for (int i = 0; i < getCount(); i++)
getSearchChapters().remove(i);
notifyDataSetChanged();
super.clear();
}
private ArrayList<Chapter> getSearchChapters()
{
ArrayList<Chapter> chapter = new ArrayList<Chapter>();
if (searchText != null)
for (int i = 0; i < DataStore.getHierarchicalChapters()
.getSubChapters().size(); i++)
{
String str = DataStore.getHierarchicalChapters()
.getSubChapters().get(i).getChapterContent()
.toLowerCase();
Pattern pat = Pattern.compile(searchText.toLowerCase());
Matcher mat = pat.matcher(str);
while (mat.find())
{mat.start()); //
chapter.add(DataStore.getHierarchicalChapters()
.getSubChapters().get(i)); // the
break;
// occurrance
}
if (DataStore.getHierarchicalChapters().getSubChapters().get(i)
.hasSubchapters())
{
for (int j = 0; j < DataStore.getHierarchicalChapters()
.getSubChapters().get(i).getSubChapters().size(); j++)
{
str = DataStore.getHierarchicalChapters()
.getSubChapters().get(i).getSubChapters()
.get(j).getChapterContent();
mat = pat.matcher(str);
while (mat.find())
{
chapter.add(DataStore.getHierarchicalChapters()
.getSubChapters().get(i).getSubChapters()
.get(j));
break;
}
}
}
}
return chapter;
}
#Override
public int getCount()
{
return getSearchChapters().size();
}
#Override
public Chapter getItem(int position)
{
return getSearchChapters().get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
if (row == null)
{
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.favorite_tab_list_view_row, parent,
false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.chapterName = (TextView) row
.findViewById(R.id.favoriteChapterTextViewId);
row.setTag(viewHolder);
}
ViewHolder viewHolder = (ViewHolder) row.getTag();
viewHolder.chapterName.setText(getSearchChapters().get(position)
.getTitle());
return row;
}
static class ViewHolder
{
public TextView chapterName;
}
public static void setSearchText(String searchText)
{
SearchListAdapter.searchText = searchText;
}
}
My question is, How can I clear the list ?
Thank You.
I think you have to override the method clear() for your custom ArrayAdapter and manually empty the list of objects on which your adapter is based(and don't forget to call notifyDataSetChanged()). This is what the default ArrayAdapter is doing.
EDIT :
Your code will never work now because your custom adapter gets its data from calling the method private ArrayList<Chapter> getSearchChapters() which rebuilds the adapter's data every time the method is called(for example every time the adapter calls getView() it will rebuild the data). My advice is to make a private field in your adapter :
ArrayList<Chapter> data;
and then in your adapter's constructor initialize it by calling the method getSearchChapters() :
data = getSearchChapters();
Then you can override the method clear():
#Override
public void clear() {
data.clear();
notifyDataSetChanged();
super.clear();
}
Also you can't call clear from onResume() because your list will never get populated with data(the adapter will be empty). I didn't understand when you want to clear the list so i can't tell you when to call the adapter.clear(). You can make a test with a button that calls clear() to see if this clears the adapter.
Clear the ArrayList that the Adapter is using then call notifyDataSetChanged() on Adapter
I have a ListView that is being populated with collection of items using a custom adapter. One of the properties of the collection is a count, and I have two TextViews in my ListView layout, one for the text and one for the count. I'd like not to display the count TextView if the count is zero. The code I have works fine when the ListView is initially loaded, but when I scroll the ListView, the count will show on random rows and constantly change if scroll the ListView up and down. This is the code I have:
public class Main extends ListActivity
{
private static CustomAdapter adapter = null;
#Override
public void onCreate(Bundle icicle)
{
List<Item> items = new ArrayList<Item>();
items = GetItems();
adapter = new CustomAdapter();
for (Item item : items)
adapter.addItem(item);
this.setListAdapter(adapter);
adapter.notifyDataSetChanged();
}
/* ADAPTER */
private class CustomAdapter extends BaseAdapter
{
private final List<Item> mData = new ArrayList<Item>();
private final LayoutInflater mInflater;
public CustomAdapter() {
mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addItem(Item item) {
mData.add(item);
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int position) {
return mData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
final ViewHolder holder;
final Item item = (Item)this.getItem(position);
if (convertView == null)
{
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.main, parent, false);
holder.text = (TextView)convertView.findViewById(R.id.text);
holder.count = (TextView)convertView.findViewById(R.id.count);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
holder.text.setText(item.getTitle());
if (item.getCount() > 0)
holder.count.setText(item.getCount().ToString());
else
holder.count.setVisibility(View.INVISIBLE);
return(convertView);
}
}
static class ViewHolder {
TextView text, count
}
Layout:
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
/>
<TextView
android:id="#+id/count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
/>
EDIT:
I was able to get it working by doing a hacky workaround. It seems setting the TextView's visibility to Invisible or Gone was causing the issue, so I just changed the color of the items with a zero count to the background color:
if (item.getCount() > 0)
holder.count.setText(item.getCount().ToString());
else
holder.count.setTextColor(Color.WHITE);
If anyone has a real fix, please let me know.
You should just do this:
if (item.getCount() > 0) {
holder.count.setText(item.getCount().ToString());
holder.count.setVisibility(View.VISIBLE);
}
else
holder.count.setVisibility(View.INVISIBLE);
Because you use a ViewHolder, you need to consider the fact that you might get an old View that's not showing the count. This means we need to make sure that the visibility of count is set to VISIBLE. Equally we want to hide it if the count is zero - so we change the visibility even though we might get a View that is all ready invisible.
I think you wrong a part of your code, Amend test this code:
if (item.getCount() > 0)
holder.count.setText(item.getCount());
else
holder.count.setVisibility(View.INVISIBLE);
Please go through this code you may helpful for the same.
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.select);
mListUsers = getUsers();
lvUsers = (ListView) findViewById(R.id.lv_user);
s = new ListAdapter(this, R.id.lv_user, mListUsers);
lvUsers.setAdapter(s);
lvUsers.setClickable(true);
// lvUsers.setTextFilterEnabled(true);
lvUsers.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,long arg3)
{
Object o = lvUsers.getItemAtPosition(position);
UserBO obj = (UserBO) o;
Intent intent = new Intent(Select.this,Update.class);
intent.putExtra("pid", ""+obj.getId());
intent.putExtra("name", obj.getName());
//put data which you want to show and select.
startActivity(intent);
}
});
}
public ArrayList<UserBO> getUsers()
{
DBAdapter dbAdapter=DBAdapter.getDBAdapterInstance(this);
try {
dbAdapter.createDataBase();
} catch (IOException e) {
//Log.i("*** select ",e.getMessage());
}
dbAdapter.openDataBase();
String query="SELECT * FROM profiledatabase";
ArrayList<ArrayList<String>> stringList = dbAdapter.selectRecordsFromDBList(query, null);
dbAdapter.close();
ArrayList<UserBO> usersList = new ArrayList<UserBO>();
for (int i = 0; i < stringList.size(); i++) {
ArrayList<String> list = stringList.get(i);
UserBO user = new UserBO();
try {
user.pid = Integer.parseInt(list.get(0));
//write code to get data from table
} catch (Exception e) {
//Log.i("***" + Select.class.toString(), e.getMessage());
}
usersList.add(user);
}
return usersList;
}
// ***ListAdapter***
private class ListAdapter extends ArrayAdapter<UserBO> {
// --CloneChangeRequired
private ArrayList<UserBO> mList;
// --CloneChangeRequired
public ListAdapter(Context context, int textViewResourceId,ArrayList<UserBO> list) {
// --CloneChangeRequired
super(context, textViewResourceId, list);
this.mList = list;
}
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
try
{
if (view == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.list_item, null);
// --CloneChangeRequired(list_item)
}
final UserBO listItem = mList.get(position);
// --CloneChangeRequired
if (listItem != null)
{
// setting list_item views
//( (TextView) view.findViewById(R.id.tv_pid) ).setText( listItem.getId()+"");
( (TextView) view.findViewById(R.id.tv_name) ).setText( listItem.getName() );
( (TextView) view.findViewById(R.id.tv_email)).setText(listItem.getEmail());
( (TextView) view.findViewById(R.id.tv_contact) ).setText( listItem.getContact()+"" );
}}catch(Exception e)
{
//Log.i(Select.ListAdapter.class.toString(), e.getMessage());
}
return view;
}
}