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

时间:2015-11-25 19:24:03

标签: android android-asynctask android-adapter

我有一个启动异步任务的适配器来查询API。我实现了一个接口,以便从onPostExecute返回一个返回值,并按照此处列出的示例覆盖适配器中的接口方法:https://stackoverflow.com/a/12575319/5605646。原始代码取自https://stackoverflow.com/a/33428678/5605646,但我想使用asyncTask来查询API。

由于return语句属于interface overriden方法,我不知道如何将该返回值传递给适配器中的另一个方法。

在适配器类中,DataBufferUtils.freezeAndClose(autocompletePredictions)返回正确的值,但传递回mResultListnew Filter()内部)的内容是null,因为getAutocomplete继续前进,直到返回空行。

有谁知道如何将值从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 个答案:

答案 0 :(得分:0)

通过执行以下操作解决了这个问题:

  1. AsyncTask class
  2. 中删除了构造函数
  3. 调用getAutocomplete(constraint),而不将返回值设置为mResultList
  4. processFinish类中覆盖Adapter作为自己的方法,而不是嵌套在另一个方法中。
  5. mResultList = DataBufferUtils.freezeAndClose(autocompletePredictions)内设置processFinish。由于mResultList是一个全局变量,因此当它在不同的方法中使用时,它已经在其中具有正确的结果。
  6. 新适配器:

    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;
    }