使用扩展BaseAdapter的自定义适配器刷新ListView

时间:2015-02-25 09:21:04

标签: android android-listview android-asynctask baseadapter onscrolllistener

我正在使用ListView,它由扩展BaseAdapter的自定义适配器填充。使用AsyncTask从外部服务器获取数据,AsyncTask的onPostExecute方法调用ListActivity上设置适配器以显示数据的方法

ListView还实现了OnScrollListener来获取滚动数据并添加到底部。

我有ActionBarToolbar)个自定义视图,其中包含EditText个字段,Button点击其中,同样AsyncTask是调用以从Toolbar传递的查询值获取新数据。

问题是,当点击工具栏上的按钮时,我希望ListView填充全新数据替换旧值,而是将新数据附加到列表底部(就像OnClickListener一样被称为。)

我检查了Link1Link2但似乎没有帮助

当然主要的打击是使用NotifyDataSetChange,我也使用它但不值得。

我设置适配器的方法

public void setBusinesses(ArrayList<BusinessListData> businesses) {

    imgFetcher = new BusinessListIconTask(this);
    layoutInflator = LayoutInflater.from(this);
    if (this.businesses == null || adapter == null) {
        this.businesses = new ArrayList<>();
        adapter = new BusinessListDataAdapter(this, imgFetcher,
                layoutInflator, this.businesses);
        businessList.setAdapter(adapter);
    }
    this.businesses.addAll(businesses);
    adapter.notifyDataSetChanged();

    /* Activates when scrolling to bottom of list */
    businessList.setOnScrollListener(new OnScrollListener() {
        public int currentScrollState;
        public int currentFirstVisibleItem;
        public int currentVisibleItemCount;
        public int totalItemCount;
        public int lastItem;
        boolean isLoading = false;

        public void onScrollStateChanged(AbsListView view, int scrollState) {
            this.currentScrollState = scrollState;
            this.isScrollCompleted();

        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                             int visibleItemCount, int totalItemCount) {
            this.currentFirstVisibleItem = firstVisibleItem;
            this.currentVisibleItemCount = visibleItemCount;
            this.totalItemCount = totalItemCount;
            this.lastItem = firstVisibleItem + visibleItemCount;
        }

        private void isScrollCompleted() {
            if (this.lastItem == this.totalItemCount) {
                /*** In this way I detect if there's been a scroll which has completed ***/
                if (!isLoading) {
                    isLoading = true;
                    getScrollData(metroTxt, metroLoc, metroId);
                }
            } else {
                businessList.removeFooterView(footerView);
            }
        }
    });

}

使用搜索字段设置自定义工具栏

void showCustomView(String metroTxt, String metroLoc, String metroId) {
    LayoutInflater mInflater = LayoutInflater.from(this);

    if (mCustomView == null)
        mCustomView = mInflater.inflate(R.layout.custom_action_bar, null);
    mToolbar.removeView(mCustomView);
    mToolbar.addView(mCustomView);
    Log.d("I'm inside custom view", "txt" + metroTxt);
    abKeyword = (CustomAutoCompleteTextView) mCustomView
            .findViewById(R.id.ab_keyword);
    abLocation = (CustomAutoCompleteTextView) mCustomView
            .findViewById(R.id.ab_location);
    ab_search = (Button) mCustomView
            .findViewById(R.id.ab_search);
    abKeyword.append(metroTxt);

    abLocation.setVisibility(View.GONE);
    ab_search.setVisibility(View.GONE);

    abKeyword.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {

            if (hasFocus || !abKeyword.getText().toString().isEmpty() || !abLocation.getText().toString().isEmpty()) {
                abLocation.setVisibility(View.VISIBLE);
                ab_search.setVisibility(View.VISIBLE);
            } else {
                abLocation.setVisibility(View.GONE);
                ab_search.setVisibility(View.GONE);
            }
        }
    });
    abKeyword.addTextChangedListener(new TextWatcher() {

        public void afterTextChanged(Editable editable) {
            // TODO Auto-generated method stub

        }

        public void beforeTextChanged(CharSequence s, int start, int count,
                                      int after) {
            // TODO Auto-generated method stub
        }

        public void onTextChanged(CharSequence s, int start, int before,
                                  int count) {

            String newText = s.toString();

            BusinessInfoSuggestionTask autocompleteTask = new BusinessInfoSuggestionTask(BusinessResultListActivity.this);
            String acType = "keyword";

            if (s.length() >= 1) {
                abLocation.setVisibility(View.VISIBLE);
                ab_search.setVisibility(View.VISIBLE);
                autocompleteTask.execute(newText, acType, cActivity);

            } else {
                abLocation.setVisibility(View.GONE);
                ab_search.setVisibility(View.GONE);
            }

        }

    });
    ab_search.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
            String abKey = abKeyword.getText().toString();
            String abLoc = abLocation.getText().toString();
            String abId = "";
            getBusinesses(abKey, abLoc, abId);
            Log.d("I'm clicked", "button on toolbar clicked");
        }
    });

}

从服务器

获取数据的方法
/* Get Businesses data from server */
private void getBusinesses(String metroTxt, String metroLoc, String metroId) {
    // TODO Auto-generated method stub
    String first = "first";
    BusinessListApiTask spTask = new BusinessListApiTask(
            BusinessResultListActivity.this);
    try {
        spTask.execute(metroTxt, metroLoc, metroId, first);
    } catch (Exception e) {
        spTask.cancel(true);
    }
}

/* Fetch more data on scroll */
private void getScrollData(String metroTxt, String metroLoc, String metroId) {
    // TODO Auto-generated method stub
    String first = "next";
    BusinessListApiTask spTask = new BusinessListApiTask(
            BusinessResultListActivity.this);
    try {
        spTask.execute(metroTxt, metroLoc, metroId, first); //Call AsyncTask to fetch data from server
    } catch (Exception e) {
        spTask.cancel(true);
    }
}

1 个答案:

答案 0 :(得分:0)

您正在使用.addAll()将数据附加到适配器已有的数据。快速解决方法是在使用.clear()调用.addAll()之前删除所有数据。

//...
this.businesses.clear();
this.businesses.addAll(businesses);
adapter.notifyDataSetChanged();
//...