2

ive implented a searchbar into my ListView and so far it works correctly except that the adapter is acting weird. Everytime i call its clear function my listview still shows the "old" content.

public abstract class MYLISTITEM extends BaseAdapter {
private Context activity;
private List<String> data;
private static LayoutInflater inflater=null;
private int ItemIcon;
private boolean moreVis;

public MYISTITEM(Context a, int IconID,boolean vis) {
    activity = a;
    data = new ArrayList<String>();  
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    ItemIcon = IconID;      
    moreVis = vis;
}

public void add(String object)
{
    data.add(object);
    notifyDataSetChanged();
}

public void replace(int index,String object)
{
    data.set(index, object);
    notifyDataSetChanged();
}

public void clear()
{
    data.clear();
    notifyDataSetChanged();
}

public void remove(Object object)
{
    data.remove(object);
    notifyDataSetChanged();
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return data.size();
}

public void insert(String object,int c)
{
    data.set(c, object);
    notifyDataSetChanged();
}

@Override
public String getItem(int position) {
    // TODO Auto-generated method stub
    if(position >= 0 && position < data.size())
    {
        return data.get(position);
    }

    return null;
}

@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}


public static class ViewHolder{
    public TextView text;
    public ImageView image;
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View vi=convertView;
    ViewHolder holder;
    if(convertView==null){
        vi = inflater.inflate(R.layout.item,parent, false);
        holder=new ViewHolder();
        holder.text=(TextView)vi.findViewById(R.id.text);
        holder.image=(ImageView)vi.findViewById(R.id.image);  
        vi.setTag(holder);
    }
    else
        holder=(ViewHolder)vi.getTag();

    holder.text.setText(data.get(position));
    holder.image.setImageDrawable(activity.getResources().getDrawable(ItemIcon));
    ImageButton btn_more = (ImageButton) vi.findViewById(R.id.more);
    if(moreVis)
    {
        btn_more.setOnClickListener(new OnMoreClickListener(btn_more,position));
    }
    else
    {
        btn_more.setVisibility(View.GONE);
    }
    vi.setOnClickListener(new OnRowClickListener(vi,position));

    return vi;
}

public abstract void OnRowClick(View mView, int position);
public abstract void OnMoreClick(View mView, int position);

private class OnRowClickListener implements OnClickListener{           
    private int mPosition;
    private View mView;
    OnRowClickListener(View view,int position){
            mPosition = position;
            mView = view;

    }
    @Override
    public void onClick(View arg0) {

        OnRowClick(mView,mPosition);
    }               
}

private class OnMoreClickListener implements OnClickListener{           
    private int mPosition;
    private View mView;
    OnMoreClickListener(View view,int position){
            mPosition = position;
            mView = view;
    }
    @Override
    public void onClick(View arg0) {

            OnMoreClick(mView,mPosition);
    }               
}    

}

the debugger shows that only the size of data has been changed but none of its content. Do i miss something here???


some additional code:

public abstract class MYSCREEN extends ListView{
public abstract void Init();
public abstract void OnLoadFinished();  
public abstract void OnRowClicked(int position);
public abstract void onCreateQuickAction(MYQUICKACTION action,int position);
public abstract void CreateOptionMenu(Menu menu);
public abstract boolean OptionsItemSelected(MenuItem item);
public MYLISTITEM adapter = null;

public static void StartupScreen(Activity current,Class<?> next)
{
    Intent myIntent = new Intent(current,next);
    current.startActivity(myIntent);
}   


public MYSCREEN(Activity context,int Icon) {
    super(context);

    boolean moreisvis = true;
    MYQUICKACTION canarybirdybirdy  = new MYQUICKACTION(new View(context));
    onCreateQuickAction(canarybirdybirdy,0);
    if(canarybirdybirdy.anchor.getVisibility() != View.VISIBLE)
    {
        moreisvis = false;
    }

    adapter = new MYLISTITEM(context,Icon,moreisvis){

        @Override
        public void OnRowClick(View mView, int position) {
            // TODO Auto-generated method stub
            OnRowClicked(position);
        }

        @Override
        public void OnMoreClick(View mView, int position) {
            // TODO Auto-generated method stub
            final MYQUICKACTION mQuickAction    = new MYQUICKACTION(mView);
            final ImageButton mMoreImage = (ImageButton) mView.findViewById(MY.views.R.id.more);
            mMoreImage.setImageResource(MY.views.R.drawable.ic_list_more_selected);

            onCreateQuickAction(mQuickAction,position);

            mQuickAction.setAnimStyle(MYQUICKACTION.ANIM_AUTO);
            mQuickAction.setOnDismissListener(new OnDismissListener() {
                @Override
                public void onDismiss() {
                    mMoreImage.setImageResource(MY.views.R.drawable.ic_list_more);
                }
            });

            mQuickAction.show();                
        }


    };
    final ProgressDialog dialog = new ProgressDialog(context);
    dialog.setMessage("loading...");
    dialog.show();
    new LOADER(){

        @Override
        public void RunThread() {   

            Init();

        }

        @Override
        public void FinishLoad() {

            dialog.dismiss();
            OnLoadFinished();
        }

    }.Start();
}


public abstract class MYTHREAD  extends AsyncTask<Void, Void, Void> {

    public abstract void InitThread();
    public abstract void RunThread();
    public abstract void FinishThread();

    @Override
    protected Void doInBackground(Void... params) {
        RunThread();
        // TODO Auto-generated method stub
        return null;
    }

    //ui stuff allowed
    @Override
    protected void onPreExecute() {
        InitThread();
    }

    //ui stuff allowed
    @Override
    protected void onProgressUpdate(Void... value) {
        super.onProgressUpdate(value);
    }

    //ui stuff allowed
    @Override
    protected void onPostExecute(final Void unused) {
        FinishThread();
    }

    public void Start()
    {
        this.execute();
    }
}       


public abstract class LOADER extends MYTHREAD{
    public abstract void FinishLoad();

    @Override
    public void InitThread() {
        // TODO Auto-generated method stub


    }

    @Override
    public void FinishThread() {
        // TODO Auto-generated method stub
        FinishLoad();

    }

}}

and here is the function that gives me the headache.Its from one of MYSCREEN derived classes , oh and its also called from the search-buttons clickevent.

    @Override
public void OnLoadFinished() {
    // TODO Auto-generated method stub
    SelectedTable = TabController.Instance.Clients[TabController.Instance.selectedtab ? 1 : 0].DbTablename;
    adapter.clear();
    TabController.Instance.Clients[TabController.Instance.selectedtab ? 1 : 0].MetaEntities(SelectedTable, true, new ClientCallBackHandler(){ 

        @Override
        public void StartCallBack() {
            // TODO Auto-generated method stub
            prgdialog.setMessage("connecting service...");
            prgdialog.show();   
        }

        @Override
        public void EndCallBack(boolean success) {
            // TODO Auto-generated method stub

            if(success)
            {
                try{
                    ExceptionResponse except = (ExceptionResponse) this.response;
                    ab.setMessage(Html.fromHtml("<b><font color=#ff0000>" + except.Message));
                    ab.setPositiveButton("ok", null);
                    ab.show();
                    success = false;
                }catch(Exception e)
                {
                    MetadataEntitiesResponse resp = (MetadataEntitiesResponse) response;
                    if(resp.Entities[0] != null)
                    {
                        Ent = resp.Entities[0];
                        int i = 0;
                        //search for the first string in our database ...

                        for(AttributeMetaData Att : Ent.Attributes)
                        {
                            if(Att.Type.contentEquals("string"))
                            {
                                SelectedAttribute = i;
                                break;
                            }
                            i++;
                        }
                        StartQuery(0); //here the adapter gets filled with info
                    }
                }
            }
        }

    }); 

}

    private void StartQuery(int page)
{
    if(currentpage != -1)
    {
        nextpage = page;
        return;
    }


    Query query = new Query();
    query.EntityName = Ent.Name;
    if(SearchFilter != null)
    {
        query.Filter = new Filter();
        query.Filter.Filters = SearchFilter;
        query.Filter.FilterOperator = Filter.E_FilterOperator.And;
    }
    query.Columns = new AllColumns();
    query.Limit = new Limit();
    query.Limit.Count = 15;
    Order order = new Order();
    order.OrderType = Order.OrderTypeE.Ascending;
    order.AttributeName = Ent.Attributes[SelectedAttribute].Name;
    query.Orders = new Order[] {order};
    currentpage = query.Limit.Page = page;

    TabController.Instance.Clients[TabController.Instance.selectedtab ? 1 : 0].RetrieveMultiple(query, new ClientCallBackHandler(){

        @Override
        public void StartCallBack() {
            // TODO Auto-generated method stub

        }

        @Override
        public void EndCallBack(boolean success) {
            // TODO Auto-generated method stub
            try{
                ExceptionResponse except = (ExceptionResponse) this.response;
                ab.setMessage(Html.fromHtml("<b><font color=#ff0000>" + except.Message));
                ab.setPositiveButton("ok", null);
                ab.show();
                success = false;
            }catch(Exception e)
            {
                RetrieveMultipleResponse rmResp = (RetrieveMultipleResponse) this.response;
                if(adapter.getCount() == 0)
                {

                    for(int i = 0; i< rmResp.TotalRecords;i++)
                    {
                        prgdialog.setMessage( ((int) (i/rmResp.TotalRecords * 100)) +  "%");
                        adapter.add("connecting...");
                    }

                    prgdialog.dismiss();
                }
                int i = 0;
                for(Entity ent : rmResp.Entities)
                {
                    adapter.replace(currentpage*15+i, ent.Properties[SelectedAttribute].ToString());
                    i++;
                }

                if(currentpage == nextpage)
                {
                    nextpage = -1;
                }
                else
                {
                    StartQuery(nextpage);
                }
                currentpage = -1;
            }               

        }


    });
}
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Alex
  • 111
  • 2
  • 2
  • 4
  • How are you getting the data from the adapter into the listview? If the size of data has changed, then surely the content has too? – RivieraKid Mar 02 '11 at 13:13

2 Answers2

5

i tried this code.. in oncreate() of where we are creating the CustomListView Adapter, call a function.

adapter.clear();

on the CustomListViewAdapter class create a function as clear

public void clear() {
    // TODO Auto-generated method stub
    movieItems.clear();

}

where movieItems is the name of the ListView

Muhammad Shakir
  • 147
  • 1
  • 12
0

Call notifyDataSetChanged() instead.

In general you use notifyDataSetInvalidated() if item properties change, and notifyDataSetChanged() if items themselves change (i.e. items are removed or added).

Reuben Scratton
  • 38,595
  • 9
  • 77
  • 86
  • Can't see any reason for it to not work. Can you post the concrete class too? (i.e. the one derived from MYLISTITEM). – Reuben Scratton Mar 02 '11 at 14:04
  • You don't call ListView.setAdapter() anywhere, AFAICS. Your Adapter class appears to be entirely unconnected to your ListView. – Reuben Scratton Mar 02 '11 at 14:33
  • unless i have to call it everytime i clear the adapter, i can assure you that it is ;) – Alex Mar 02 '11 at 14:51
  • oh and i also made some screenshots (might show my problem a bit better) http://img856.imageshack.us/i/29370315.jpg/ http://img202.imageshack.us/i/63572833.jpg/ everything within the green frame is whats currently in the adapter , everything in the red one shouldnt be there anymore... – Alex Mar 02 '11 at 15:03
  • You don't have to call setAdapter() every time you clear() the adapter's list, but you do have to call it once. Your code doesn't appear to do so. Also, when are you adding new data after clear() and how? At the moment I suspect the problem is how you are using the code thus far posted. – Reuben Scratton Mar 02 '11 at 15:18
  • only stuff in OnLoadFinished and StartQuery should matter because everything else is basically the same as in other derived classes from MYSCREEN, all other MYSCREENs (except for one) use a very similar way to refresh themself and it works for them... – Alex Mar 02 '11 at 15:41
  • Isn't the problem then likely to be in your one MYSCREEN-derived class? What is the difference between the working MYSCREENs and the non-working one? – Reuben Scratton Mar 02 '11 at 16:39
  • found the problem,my onScrollListener was causing an infinite loop ^^ (somebody should have told me that "public void onScroll" is called everytime even if i dont scroll) – Alex Mar 03 '11 at 09:24
  • A false observation in the original question then. Oh well, it happens. Suggest you delete this question. – Reuben Scratton Mar 03 '11 at 16:55