来自Volley JsonArrayRequest的AutocompleteTextView数据

时间:2018-12-28 19:11:45

标签: android android-volley autocompletetextview

我正在尝试从PHP返回的数据中以JSON格式填充AutoCompleteTextView的应用程序。该应用程序可以编译,但是我似乎无法弄清问题所在。问题是Volley是异步的,我不知道在加载建议之前如何等待响应。

在相同的设置下,我尝试通过使用以下代码更改retrieveOffices()方法从应用程序内部创建数据:

private List<office_location_data> retrievePeople() {
        List<office_location_data> list = new ArrayList<office_location_data>();
        list.add(new office_location_data(1, "Bond"));
        list.add(new office_location_data(2, "Cat"));
        list.add(new office_location_data(3, "Dog"));
        return list;
    }

这将正常工作,并在输入第一个字母时显示选项。任何帮助表示赞赏。

以下是无效的代码。

我的活动是:

package tz.co.fsm.fas;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.AutoCompleteTextView;
import android.widget.Button;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class registerStep2 extends AppCompatActivity {

    private String url;
    SharedPreferences preferences;
    SharedPreferences.Editor edit;
    AutoCompleteTextView txtOfficeLocation, txtDepartment;
    Button btnCompleteRegistration;
    office_locations_adapter adapter;
    List<office_location_data> listOffices;
    List<office_location_data> list = new ArrayList<>();

    // Import Class fas_functions
    fas_functions Fas = new fas_functions(this);

    private List<office_location_data> retrieveOffices() {
        // Initiate Volley queue
        RequestQueue queue = Volley.newRequestQueue(getApplicationContext());

        // Add the api location (For JSON Requests we have to use GET and out the parameters in the url string (From Volley)
        url = preferences.getString("server", "") + "/api/getofficelocations.php";

        // Do the request and load the data into the array list to be used on autocomplete
        JsonArrayRequest req = new JsonArrayRequest(Request.Method.GET, url ,null, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray response) {
                try {
                    for (int i = 0; i < response.length(); i++) {
                        JSONObject obj = response.getJSONObject(i);
                        list.add(new office_location_data(obj.getInt("office_id"), obj.getString("office_location")));
                        //list.add(new office_location_data(obj.getInt("office_id"), obj.getString("office_location")));
                    }

                } catch (JSONException e) {
                    System.out.println(e.toString());
                }

                // Tell the adapter we have retrieved data and display
                adapter.notifyDataSetChanged();
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                System.out.println(error.toString());
            }
        });

        queue.add(req);

        return list;
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register_step2);

        // Get elements
        txtOfficeLocation = findViewById(R.id.txtOfficeLocation);
        txtDepartment = findViewById(R.id.txtDeparment);
        btnCompleteRegistration = findViewById(R.id.btnCompleteRegistration);

        // Application preferences to check if we have already registered
        preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        // Immediately request for location permission
        Fas.checkLocationPermission(this);

        Fas.checkGPSandMobile(this);

        listOffices = retrieveOffices();

        adapter = new office_locations_adapter(getApplicationContext(), R.layout.office_locations_adapter_row,R.id.rowtxtOfficeLocation, listOffices);
        txtOfficeLocation.setAdapter(adapter);

        // Application preferences to check if we have already registered
        preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        TextWatcher textWatcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

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

            }

            @Override
            public void afterTextChanged(Editable s) {
                // Check if all fields are full so we can proceed
                if (!txtOfficeLocation.getText().toString().isEmpty() && !txtDepartment.getText().toString().isEmpty()) {
                    btnCompleteRegistration.setEnabled(true);
                } else {
                    btnCompleteRegistration.setEnabled(false);
                }
            }
        };

        txtOfficeLocation.addTextChangedListener(textWatcher);
        txtDepartment.addTextChangedListener(textWatcher);
    }

    private void completeRegistration() {
        // Edit the preferences
        edit = preferences.edit();
        // We have completed step 2 so add to preferences
        edit.putBoolean("registrationstep2done", true);
    }


} /* End of class */

自定义适配器如下:

package tz.co.fsm.fas;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class office_locations_adapter extends ArrayAdapter<office_location_data> {
    private Context context;
    int resource, textViewResourceId;
    private List<office_location_data> items, tempItems, suggestions;

    public office_locations_adapter(Context context, int resource, int textViewResourceId, List<office_location_data> items) {
        super(context, resource, textViewResourceId, items);
        this.context = context;
        this.resource = resource;
        this.textViewResourceId = textViewResourceId;
        this.items = items;
        tempItems = new ArrayList<>(items); // this makes the difference.
        suggestions = new ArrayList<>();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.office_locations_adapter_row, parent, false);
        }

        office_location_data office = items.get(position);

        if (office != null) {
            TextView lbloffice = view.findViewById(R.id.rowtxtOfficeLocation);
            if (lbloffice != null) {
                lbloffice.setText(office.getOffice_location());
            }
        }

        return view;
    }

    // Method to return the filter
    @Override
    public Filter getFilter() {
        return performFiletring;
    }

    // Create a new filter. Here we perform the filtering results and use this in the getFilter() method
    Filter performFiletring = new Filter() {
        @Override
        public CharSequence convertResultToString(Object resultValue) {
            String str = ((office_location_data) resultValue).getOffice_location();
            return str;
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            if (constraint != null) {
                suggestions.clear();
                for (office_location_data offices : tempItems) {
                    if (offices.getOffice_location().toLowerCase().contains(constraint.toString().toLowerCase())) {
                        suggestions.add(offices);
                    }
                }
                FilterResults filterResults = new FilterResults();
                filterResults.values = suggestions;
                filterResults.count = suggestions.size();
                return filterResults;
            } else {
                return new FilterResults();
            }
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            List<office_location_data> filteredOffices = (ArrayList<office_location_data>) results.values;
            if (results != null && results.count > 0) {
                filteredOffices.clear();
                for (office_location_data offices : filteredOffices) {
                    add(offices);
                    notifyDataSetChanged();
                }
            }
        }
    };
}

包含数据的类:

package tz.co.fsm.fas;

// Class to hold data for the autocomplete on the registration activity
public class office_location_data {
    int office_id;
    String office_location;

    public void setOffice_id(int office_id) {
        this.office_id = office_id;
    }

    public void setOffice_location(String office_location) {
        this.office_location = office_location;
    }

    public int getOffice_id() {
        return office_id;

    }

    public String getOffice_location() {
        return office_location;
    }

    public office_location_data(int office_id, String office_location) {
        this.office_id = office_id;
        this.office_location = office_location;
    }
}

自动完成行的布局为:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="8dp"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/rowtxtOfficeLocation"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>
</android.support.constraint.ConstraintLayout>

0 个答案:

没有答案