質問

Im using the cwac-endless EndlessAdapter with a custom ListViewAdapter. With an AsyncTask i get the data form he webserver in 2 phases. 1) i get all the id's of the elements 2) using the EndlessAdapter i want to load say 4 elements at a time (i get from the server 4 elements by their id)

The problem that im facing is that as i create my custom ListViewAdapter when i call the contructor of MyEndlessAdapter which creates the list of items with the first bach of items. when i load the next batch of elements my custom ListViewAdapter it gets the correct items from the server but i recycles the getView(graphic/visual stuff). What am i doing wrong!

I think a possible solution bwould be to use the add method of the CustomListView but i dont know how to call it from the CompraFragment class.

How do i solve this problem? Thanks

ListViewAdapter code:

public class ListViewAdapter extends ArrayAdapter<Item> {

    private LayoutInflater inflater = null;
    private final String TAG = "ListViewAdapter";
    public Context context; 
    public int layoutResourceId;
    public ArrayList<Item> items;


    public ListViewAdapter(Context context, int listviewItemRow, ArrayList<Item> items) {
        // TODO Auto-generated constructor stub
        super(context, listviewItemRow);
        this.context = context;
        this.items = items; 

    }

    public ListViewAdapter(Context context, int listviewItemRow) {
        super(context, listviewItemRow);
        this.context = context;
    }


    @Override
    public void add(Item object) {
        Log.i(TAG, "---ADD---");
        items.add(object);
        //super.add(object);
    }

    @Override
    public void clear() {
        super.clear();
    }

    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();
    }

    @Override
    public void remove(Item object) {
        super.remove(object);
    }

    @Override
    public int getCount() {
        return items.size();
    }

    public Item getItem(Item position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        Item item = items.get(position);
        Log.w(TAG, "view of Item " + item.getId() + " at position " + position);

        ItemView view;
        if (convertView == null) {
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = (ItemView) inflater.inflate(R.layout.listview_item_row, null);
            view.checkFollowing(item, this, 3);
            view.setTag(Long.toString(item.getId()));       
            Log.e(TAG, "CREATED ITEM " + item.getId() + " at position " + position);
        } else {
            view = (ItemView) convertView;
            Log.i(TAG, "RECYCLED ITEM " + item.getId() + " at position " + position);
        }   

        view.setOnClickListener(new OnItemClickListener(position));



        view.showItems(item);
        return view;
    }


    private class OnItemClickListener implements OnClickListener {

        private int mPosition;

        private OnItemClickListener(int position){
            mPosition = position;
        }

        @Override
        public void onClick(View v) {
            Toast.makeText(context, "Message " + Integer.toString(mPosition), Toast.LENGTH_SHORT).show();

            Intent intent = new Intent(context, DettagliActivity.class);
            Bundle bundle = new Bundle();
            bundle.putInt("id", mPosition);
            intent.putExtras(bundle);
            context.startActivity(intent);
        }   
    }

}

CompraFragment code:

public class CompraFragment extends ListFragment {

    private static final String TAG = "CompraFragment";
    public ListView listView;
    public MyEndlessAdapter adapter = null;
    public ListViewAdapter mListViewAdapter;

    private DownloadTask mDownloadTask = null;

    public ArrayList<Item> items;
    public ArrayList<Long> ids; 
    public Bitmap icon;
    public int currentItemId = 0;

    public String category = "";
    public String latitude = "";
    public String longitude = "";
    public String radius = "";
    public String keywords = "";
    public String order = "";
    public String state = "2";

    //numero di elementi caricabili sulla wall all volta
    public final int BATCH_SIZE = 4;    

    public ProgressDialog progressDialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);  
        setHasOptionsMenu(true);
        progressDialog = new ProgressDialog(this.getActivity());
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar actions click
        switch (item.getItemId()) {
        case R.id.action_aggiorna:

            items = new ArrayList<Item>();
            ids = new ArrayList<Long>();

            mDownloadTask = new DownloadTask();
            mDownloadTask.execute();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }


    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // TODO Auto-generated method stub
        inflater.inflate(R.menu.compra, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.i(TAG, "onCreateView");
        Bundle extras = getActivity().getIntent().getExtras();

        if (extras != null){
            category = (String) extras.get("category");
            latitude = (String) extras.get("latitude");
            longitude = (String) extras.get("radius");
            radius = (String) extras.get("radius");
            keywords = (String) extras.get("keywords");
            order = (String) extras.get("order");
            state = (String) extras.get("state");
        }

        View rootView = inflater.inflate(R.layout.fragment_compra, container, false); 

        // now you must initialize your list view
        listView = (ListView) rootView.findViewById(android.R.id.list); 

        mDownloadTask = new DownloadTask();
        mDownloadTask.execute();

        return rootView;
    }



    /**
     * Represents an asynchronous  task used to download
     * information from the webserver and display the results
     */
    public class DownloadTask extends AsyncTask<Integer, Void, Boolean> {

        @Override
        protected Boolean doInBackground(Integer... params) {           
            ids = new ArrayList<Long>();    

            ids = MVPFunctions.getInstance().search(category, latitude, longitude, radius, keywords, order, state);

            if (ids.isEmpty()){
                return false;
            } else { 
                Log.i(TAG, "ids size = " + ids.size());
            }
            return true;
        }

        @Override
        protected void onPreExecute(){
            /*
             * This is executed on UI thread before doInBackground(). It is
             * the perfect place to show the progress dialog.
             */
            //progressDialog = ProgressDialog.show(getActivity(), "", "Downloading Content...");
            progressDialog.setMessage("Downloading Content...");
            progressDialog.show();
        }

        @Override
        protected void onPostExecute(final Boolean success) {
            mDownloadTask = null;

            if (!success){
                Log.i("onPostExecute", "items null");
                Toast.makeText(getActivity(), "Non ci sono elementi da caricare", Toast.LENGTH_LONG).show();
            } else {
                items = new ArrayList<Item>();
                adapter = new MyEndlessAdapter(items);
                adapter.setRunInBackground(false);
                listView.setAdapter(adapter);
            }
        }

        @Override
        protected void onCancelled() {
            mDownloadTask = null;
        }       
    }


    class MyEndlessAdapter extends EndlessAdapter implements IItemsReadyListener {
        private RotateAnimation rotate = null;

        MyEndlessAdapter(ArrayList<Item> list) {
            super(new ListViewAdapter(getActivity(),R.layout.listview_item_row, list));
            rotate = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            rotate.setDuration(600);
            rotate.setRepeatMode(Animation.RESTART);
            rotate.setRepeatCount(Animation.INFINITE);

            Log.i(TAG, "CONSTRUCTER CALLED");
        }


        @Override
        protected View getPendingView(ViewGroup parent) {
            View row = getActivity().getLayoutInflater().inflate(R.layout.listview_item_row, null);
            View child;

            child = row.findViewById(R.id.relativeLayout);
            child.setVisibility(View.GONE);

            child = row.findViewById(R.id.throbber);
            child.setVisibility(View.VISIBLE);
            child.startAnimation(rotate);

            return (row);
        }

        @Override
        protected boolean cacheInBackground() throws Exception {            
            //Log.i(TAG, "cacheInBackground - items.size(): " + items.size());

            new FetchDataTask(this, items.size()).execute();

            if (items.size() < ids.size() ){
                return true;
            } else {
                return false;
            }
        }

        @Override
        public void onItemsReady(ArrayList<Item> data) {
            Log.e(TAG, "onItemsReady");
            items.addAll(data);

            // Tell the EndlessAdapter to remove it's pending view and call notifyDataSetChanged()
            adapter.onDataReady();
            progressDialog.dismiss();
        }

        @Override
        protected void appendCachedData() {
            // TODO Auto-generated method stub
        }
    }

    interface IItemsReadyListener {
        public void onItemsReady(ArrayList<Item> data);
    }

    class FetchDataTask extends AsyncTask<Void, Void, ArrayList<Item>> {
        private static final String TAG = "FetchDataTask";

        IItemsReadyListener listener;

        //The point from where to start counting.
        int startPoint;


        protected FetchDataTask(IItemsReadyListener listener, int startPoint) {
            this.listener = listener;
            this.startPoint = startPoint;
        }

        @Override
        protected ArrayList<Item> doInBackground(Void... params) {
            ArrayList<Item> result = new ArrayList<Item>();

            Item item;
            for (int i = startPoint; ((i < ids.size()) && (i < startPoint + BATCH_SIZE)); i++) {
                Log.i(TAG, "i = " + i);
                item = MVPFunctions.getInstance().getItem(ids.get(i));
                result.add(item);
            }
            return (result);
        }

        @Override
        protected void onPostExecute(ArrayList<Item> result) {
            listener.onItemsReady(result);

        }
    }
}

ItemView code:

public class ItemView extends LinearLayout {

    public TextView prezzo;
    public TextView scadenza;
    public TextView followers;
    public ImageView ic_thumbnail;
    public ProgressBar hProgressBar;
    public ToggleButton followButton;
    public String nextFollowAction = "";
    public ListViewAdapter lva;

    public String mLogin;
    public String mPassword;

    public int statusCode;
    public Item item;


    public BackgroundTask mBackgroundTask = null;


    public ItemView(Context context, AttributeSet attrs) {
        super(context, attrs);      

    }



    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        prezzo = (TextView)findViewById(R.id.tvPrezzo);
        scadenza = (TextView)findViewById(R.id.tvScadenza);
        followers = (TextView)findViewById(R.id.tvFollowers);
        ic_thumbnail = (ImageView)findViewById(R.id.ic_thumbnail);
        hProgressBar = (ProgressBar)findViewById(R.id.hProgressBar);
        followButton = (ToggleButton)findViewById(R.id.btnFollow);
    }

    public void showItems(final Item item) {
        prezzo.setText(item.getPrezzo());
        ic_thumbnail.setImageBitmap(item.getIcon());
        scadenza.setText(item.getScadenza());
        followers.setText("Followers:    " + item.getFollowers());
        hProgressBar.setProgress(item.getCoefficient());
        followButton.setTag(item.getId());
    }


    public void askForFollowing(String nextFollowAction, final Item item, final int statusCode){

        //Log.e("status code fo item is", Integer.toString(statusCode) + " " + item.getId());
        //Status code: 0 --> OK     
        if(statusCode == 0) {
            //Log.i("statusCode == 0", "richiesta evasa correttamente");
            changeFollowStatus(nextFollowAction, item);
         }

         // Status code 108 --> Oggetto già seguito
         else if ((statusCode == 108) && (nextFollowAction.contains("kCheckFollowAction"))) {
            //Log.i("statusCode == 108", "gray");
            nextFollowAction = "kUnfollowAction";
            followButton.setEnabled(true);
            followButton.setBackgroundResource(R.drawable.action_object_button_gray);
            followButton.setText("seguito");
            lva.notifyDataSetChanged();

            followButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    view.setEnabled(false);
                    setFollowing("kUnfollowAction", item, (long) 2);
                }
            });
         }

         // Status code 122 --> Oggetto non ancora seguito
         else if ((statusCode == 122) && (nextFollowAction.contains("kCheckFollowAction"))) {
            //Log.i("statusCode == 122", "green");
            nextFollowAction = "kFollowAction";
            followButton.setEnabled(true);
            followButton.setBackgroundResource(R.drawable.action_object_button_green);
            followButton.setText("segui");
            lva.notifyDataSetChanged();

            followButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {                
                    view.setEnabled(false);
                    setFollowing("kFollowAction", item, (long) 1);
                }
            });

         }  else {
             Log.e("error", "error non e ne 0 ne 108 ne 122");
             Log.e("error", nextFollowAction);
             Log.e("error", Long.toString(item.getId()));
             Log.e("error", Integer.toString(statusCode));
         }

    }

    public void changeFollowStatus(String nextFollowAction, Item item){
        //Log.i("changeFollowStatus action", nextFollowAction);

        if(nextFollowAction.contains("kFollowAction")) {
            //Log.w("changeFollowStatus increase", "+1");
            nextFollowAction = "kUnfollowAction";
            followButton.setBackgroundResource(R.drawable.action_object_button_gray);
            followButton.setText("seguito");
            followButton.getTextOn();
            increaseFollowers(item);        
        }
        else if(nextFollowAction.contains("kUnfollowAction")){
            //Log.w("changeFollowStatus decrease", "-1");
            nextFollowAction = "kFollowAction";
            followButton.setBackgroundResource(R.drawable.action_object_button_green);
            followButton.setText("segui");
            followButton.getTextOff();
            decreaseFollowers(item);
        }
    }

    public void increaseFollowers(Item item){
        int updatedFollowers = Integer.parseInt(item.getFollowers()) + 1;
        item.setFollowers(Integer.toString(updatedFollowers));
        followers.setText("Followers:    " + item.getFollowers());
    }

    public void decreaseFollowers(Item item){
        int updatedFollowers = Integer.parseInt(item.getFollowers()) - 1;
        item.setFollowers(Integer.toString(updatedFollowers));
        followers.setText("Followers:    " + item.getFollowers());
    }

    public void checkFollowing(Item item, ListViewAdapter listViewAdapter, long follow) {

        this.lva = listViewAdapter;

        mBackgroundTask = new BackgroundTask();
        try {
            int statusCode = mBackgroundTask.execute(item.getId(), follow).get();
            askForFollowing("kCheckFollowAction", item, statusCode);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }

    public void setFollowing(String nextFollowAction, Item item, Long follow){

        mBackgroundTask = new BackgroundTask();

        try {
            int statusCode = mBackgroundTask.execute(item.getId(), follow).get();

            /*
            Log.i("setFollowing p1", Long.toString(follow));
            Log.i("setFollowing p1", nextFollowAction);
            Log.i("setFollowing p2", Long.toString(item.getId()));
            Log.i("setFollowing p3", Integer.toString(statusCode));
            */
            askForFollowing(nextFollowAction, item, statusCode);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }



    /**
     * Represents an asynchronous  task used to download
     * information from the webserver and display the results
     */
    public class BackgroundTask extends AsyncTask<Long, Void, Integer> {

        private int statusCode; 

        @Override
        protected Integer doInBackground(Long... params) {
            // TODO: attempt authentication against a network service.



            statusCode = MVPFunctions.getInstance().followItem(mLogin, mPassword, params[0], params[1].intValue());

            return statusCode;
        }

        @Override
        protected void onPreExecute(){
            /*
             * This is executed on UI thread before doInBackground(). It is
             * the perfect place to show the progress dialog.
             */
        }

        @Override
        protected void onPostExecute(Integer result) {
            mBackgroundTask = null;

            //askForFollowing("kCheckFollowAction", item, statusCode);

            //listViewAdapter.notifyDataSetChanged();

            //result1 = listener.processFinish(result);

            //setStatusCode(result);

            //delegate.processFinish(result);
            //ItemView
            //Log.i("onPostExecute statusCode", Integer.toString(success) + " = " + Integer.toString(statusCode));
        }

        @Override
        protected void onCancelled() {
            mBackgroundTask = null;
        }
    }
}
役に立ちましたか?

解決

When a view is recycled [i.e., passed to getView() as a non-null convertView], you need to update it to reflect the state of the current item. So, the 2 lines indicated below need to be moved after the if/then block.

public View getView(final int position, View convertView, ViewGroup parent) {

    Item item = items.get(position);
    Log.w(TAG, "view of Item " + item.getId() + " at position " + position);

    ItemView view;
    if (convertView == null) {
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = (ItemView) inflater.inflate(R.layout.listview_item_row, null);
        Log.e(TAG, "CREATED ITEM " + item.getId() + " at position " + position);
    } else {
        view = (ItemView) convertView;
        Log.i(TAG, "RECYCLED ITEM " + item.getId() + " at position " + position);
    }

    // ===> These 2 lines always need to be executed. <===
    view.checkFollowing(item, this, 3);
    view.setTag(Long.toString(item.getId()));       

    view.setOnClickListener(new OnItemClickListener(position));

    view.showItems(item);
    return view;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top