Android - 将适配器中覆盖接口方法的返回值传递给适配器中的另一个方法

Android - pass returned value from overriden interface method in adapter to another method in adapter

我有一个适配器启动异步任务来查询 API。我实现了一个接口以便从 onPostExecute 获取 return 值,并按照此处列出的示例覆盖适配器中的接口方法:. The original code is taken from ,但我想使用 asyncTask 用于查询 API.

由于 return 语句属于接口覆盖方法,我不知道如何将 returned 值传递给适配器中的另一个方法。

在适配器 class 中,DataBufferUtils.freezeAndClose(autocompletePredictions) return 是正确的值,但是传递回 mResultList(在 new Filter() 内)的是 null,因为 getAutocomplete 一直持续到 return 空行。

有谁知道如何将值从 DataBufferUtils.freezeAndClose(autocompletePredictions) 传递到 mResultList

适配器

public class PlaceAutocompleteAdapter extends  ArrayAdapter<AutocompletePrediction> implements Filterable
{
    private static final String TAG = "PlaceAutocompleteAdapter";
    private static final CharacterStyle STYLE_BOLD = new    StyleSpan(Typeface.BOLD);
    private ArrayList<AutocompletePrediction> mResultList;
    private GoogleApiClient mGoogleApiClient;
    private LatLngBounds mBounds;
    private AutocompleteFilter mPlaceFilter;

public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,LatLngBounds bounds, AutocompleteFilter filter){

    super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
    mGoogleApiClient = googleApiClient;
    mBounds = bounds;
    mPlaceFilter = filter;
}

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

@Override
public AutocompletePrediction getItem(int position){
    return mResultList.get(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = super.getView(position, convertView, parent);
    AutocompletePrediction item = getItem(position);
    TextView textView1 = (TextView) row.findViewById(android.R.id.text1);
    TextView textView2 = (TextView) row.findViewById(android.R.id.text2);
    textView1.setText(item.getPrimaryText(STYLE_BOLD));
    textView2.setText(item.getSecondaryText(STYLE_BOLD));

    return row;
}

// returns the filter for the current set of autocomplete results
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();

            //skip the autocomplete query if no constraints are given
            if (constraint != null) {

                // query the autocomplete API for the search string
                mResultList = getAutocomplete(constraint);

                if (mResultList != null) {

                    //the API successfully returned results
                    results.values = mResultList;
                    results.count = mResultList.size();

                }
            }
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results != null && results.count > 0) {
                Log.i("notifyDataSetChanged","results are not null");
                // The API returned at least one result, update the data.
                notifyDataSetChanged();
            } else {
               Log.i("notifyDataSetInvalid", "results are null");
                // The API did not return any results, invalidate the data set.
                notifyDataSetInvalidated();
            }
        }

        @Override
        public CharSequence convertResultToString(Object resultValue) {
            // override this method to display a readable result in the AutocompleteTextView
            // when clicked.
            if (resultValue instanceof AutocompletePrediction) {
                return ((AutocompletePrediction) resultValue).getFullText(null);
            } else {
                return super.convertResultToString(resultValue);
            }
        }
    };
}

        public ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {

            if (mGoogleApiClient.isConnected()) {

                MyTaskParams params = new MyTaskParams(constraint, mGoogleApiClient, mBounds, mPlaceFilter);
                updateSuggestionAsync myTask = new updateSuggestionAsync(new AsyncResponse(){

                    @Override
                    public ArrayList<AutocompletePrediction> processFinish(AutocompletePredictionBuffer autocompletePredictions){

                        // Confirm that the query completed successfully, otherwise return null
                        final com.google.android.gms.common.api.Status status = autocompletePredictions.getStatus();
                        if (!status.isSuccess()) {
                            Log.i("Error contacting API","Error contacting API");
                            Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
                                    Toast.LENGTH_SHORT).show();
                            autocompletePredictions.release();
                            return null;
                        }

                        // Freeze the results immutable representation that can be stored safely.
                        return  DataBufferUtils.freezeAndClose(autocompletePredictions);
                    }
                });
                myTask.execute(params);

            }
           return null;
        }
   }

AsyncTask

public class updateSuggestionAsync extends  AsyncTask<MyTaskParams,Void,AutocompletePredictionBuffer>{

   public AsyncResponse delegate = null;

   public updateSuggestionAsync (AsyncResponse delegate){
       this.delegate = delegate;
   }

    @Override
    protected AutocompletePredictionBuffer  doInBackground(MyTaskParams...params){

        CharSequence constraint = params[0].constraint;
        GoogleApiClient mGoogleApiClient = params[0].mGoogleApiClient;
        LatLngBounds mBounds = params[0].mBounds;
        AutocompleteFilter mPlaceFilter = params[0].mPlaceFilter;

        PendingResult<AutocompletePredictionBuffer> results =
        Places.GeoDataApi.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),mBounds,mPlaceFilter);

        return results.await(60, TimeUnit.SECONDS);
}

    @Override
    protected void onPostExecute(AutocompletePredictionBuffer result){
            delegate.processFinish(result);
}
}

界面

public interface AsyncResponse {
    public ArrayList<AutocompletePrediction> processFinish((AutocompletePredictionBuffer output);
 }

通过执行以下操作解决了它:

  1. AsyncTask class
  2. 中删除了构造函数
  3. 调用了 getAutocomplete(constraint),没有将 return 值设置为 mResultList
  4. Adapter class 中将 processFinish 重写为它自己的方法,而不是嵌套在另一个方法中。
  5. processFinish 内设置 mResultList = DataBufferUtils.freezeAndClose(autocompletePredictions)。由于 mResultList 是一个全局变量,当它在不同的方法中使用时,它已经有了正确的结果。

新适配器:

public class PlaceAutocompleteAdapter extends ArrayAdapter<AutocompletePrediction> implements Filterable,AsyncResponse
{

private static final String TAG = "PlaceAutocompleteAdapter";
private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);

// Current results returned by this adapter.
private ArrayList<AutocompletePrediction> mResultList;

// Handles autocomplete requests.
private GoogleApiClient mGoogleApiClient;

// The bounds used for Places Geo Data autocomplete API requests.
private LatLngBounds mBounds;

// The autocomplete filter used to restrict queries to a specific set of place types.
private AutocompleteFilter mPlaceFilter;

//constructor
public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,
                                LatLngBounds bounds, AutocompleteFilter filter){

super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
    mGoogleApiClient = googleApiClient;
    mBounds = bounds;
    mPlaceFilter = filter;
}

 //returns the number of results received in the last autocomplete query
@Override
public int getCount(){
    return mResultList.size();
}

// returns an item from the last autocomplete query
@Override
public AutocompletePrediction getItem(int position) {
    return mResultList.get(position);
}

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

    View row = super.getView(position, convertView, parent);

    // sets the primary and secondary text for a row.
    // note that getPrimaryText() and getSecondaryText() return a CharSequence that may
    // contain styling based on the given CharacterStyle

    AutocompletePrediction item = getItem(position);

    TextView textView1 = (TextView) row.findViewById(android.R.id.text1);
    TextView textView2 = (TextView) row.findViewById(android.R.id.text2);
    textView1.setText(item.getPrimaryText(STYLE_BOLD));
    textView2.setText(item.getSecondaryText(STYLE_BOLD));

    return row;
}

// returns the filter for the current set of autocomplete results
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();

            //skip the autocomplete query if no constraints are given
            if (constraint != null) {

                getAutocomplete(constraint);

                if (mResultList != null) {
                    //the API successfully returned results
                    results.values = mResultList;
                    results.count = mResultList.size();
                }
            }
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results != null && results.count > 0) {
                Log.i("notifyDataSetChanged","results are not null");
                // The API returned at least one result, update the data.
                notifyDataSetChanged();
            } else {
               Log.i("notifyDataSetInvalid", "results are null");
                // The API did not return any results, invalidate the data set.
                notifyDataSetInvalidated();
            }
        }

        @Override
        public CharSequence convertResultToString(Object resultValue) {
            // override this method to display a readable result in the AutocompleteTextView
            // when clicked.
            if (resultValue instanceof AutocompletePrediction) {
                return ((AutocompletePrediction) resultValue).getFullText(null);
            } else {
                return super.convertResultToString(resultValue);
            }
        }
    };
}

        public void  getAutocomplete(CharSequence constraint) {

            if (mGoogleApiClient.isConnected()) {
                MyTaskParams params = new MyTaskParams(constraint, mGoogleApiClient, mBounds, mPlaceFilter);

                updateSuggestionAsync myTask = new updateSuggestionAsync();
                myTask.delegate=this;
                myTask.execute(params);
            }
        }

@Override
public ArrayList<AutocompletePrediction> processFinish(AutocompletePredictionBuffer autocompletePredictions){
    Log.i("made it processFinish","made it processFinish");
    // Confirm that the query completed successfully, otherwise return null
    final com.google.android.gms.common.api.Status status = autocompletePredictions.getStatus();
    if (!status.isSuccess()) {
        Log.i("Error contacting API","Error contacting API");
        Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
                Toast.LENGTH_SHORT).show();
        autocompletePredictions.release();
        return null;
    }
    mResultList = DataBufferUtils.freezeAndClose(autocompletePredictions);
    // Freeze the results immutable representation that can be stored safely.
    return  mResultList;
}