Development Tip

AutoCompleteTextView를 사용하고 웹 API의 데이터로 채우려면 어떻게합니까?

yourdevel 2020. 10. 5. 21:02
반응형

AutoCompleteTextView를 사용하고 웹 API의 데이터로 채우려면 어떻게합니까?


AutoCompleteTextView내 활동에서 를 사용 하고 웹 API를 쿼리하여 사용자가 입력 할 때 데이터를 채우고 싶습니다. 어떻게해야합니까?

새 클래스를 만들고 재정의 AutoCompleteTextView.performFiltering합니까, 아니면 사용자 지정 목록 어댑터를 사용하고 android.widget.FilterperformFiltering을 재정의 하는 사용자 지정 제공 합니까?

아니면 최종 목표를 달성하는 더 좋은 방법이 있습니까?

비슷한 작업을 수행했지만 빠른 검색 상자를위한 것이었고 서비스 구현과 관련이 있었지만 여기서는 그렇게하고 싶지 않다고 생각합니다.


나는 해결책을 생각해 냈고 그것이 최선의 해결책인지는 모르겠지만 매우 잘 작동하는 것 같습니다. 내가 한 일은 ArrayAdapter를 확장하는 사용자 지정 어댑터를 만든 것입니다. 사용자 지정 어댑터에서 getFilter를 재정의하고 performFiltering을 재정의하는 고유 한 Filter 클래스를 만들었습니다. 이렇게하면 새 스레드가 시작되므로 UI가 중단되지 않습니다. 아래는 베어 본 예제입니다.

MyActivity.java

public class MyActivity extends Activity {
    private AutoCompleteTextView style;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        style = (AutoCompleteTextView) findViewById(R.id.style);
        adapter = new AutoCompleteAdapter(this, android.R.layout.simple_dropdown_item_1line); 
        style.setAdapter(adapter);
    }
}

AutoCompleteAdapter.java

public class AutoCompleteAdapter extends ArrayAdapter<Style> implements Filterable {
    private ArrayList<Style> mData;

    public AutoCompleteAdapter(Context context, int textViewResourceId) {
        super(context, textViewResourceId);
        mData = new ArrayList<Style>();
    }

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

    @Override
    public Style getItem(int index) {
        return mData.get(index);
    }

    @Override
    public Filter getFilter() {
        Filter myFilter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults filterResults = new FilterResults();
                if(constraint != null) {
                    // A class that queries a web API, parses the data and returns an ArrayList<Style>
                    StyleFetcher fetcher = new StyleFetcher();
                    try {
                        mData = fetcher.retrieveResults(constraint.toString());
                    }
                    catch(Exception e) {
                        Log.e("myException", e.getMessage());
                    }
                    // Now assign the values and count to the FilterResults object
                    filterResults.values = mData;
                    filterResults.count = mData.size();
                }
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence contraint, FilterResults results) {
                if(results != null && results.count > 0) {
                notifyDataSetChanged();
                }
                else {
                    notifyDataSetInvalidated();
                }
            }
        };
        return myFilter;
    }
}

AJ에서 확장 . 의 답변 위의 다음 사용자 정의 어댑터에는 서버 요청 처리 및 json 구문 분석도 포함됩니다.

class AutoCompleteAdapter extends ArrayAdapter<String> implements Filterable
{
    private ArrayList<String> data;
    private final String server = "http://myserver/script.php?query=";

    AutoCompleteAdapter (@NonNull Context context, @LayoutRes int resource)
    {
        super (context, resource);
        this.data = new ArrayList<>();
    }

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

    @Nullable
    @Override
    public String getItem (int position)
    {
        return data.get (position);
    }

    @NonNull
    @Override
    public Filter getFilter()
    {
        return new Filter()
        {
            @Override
            protected FilterResults performFiltering (CharSequence constraint)
            {
                FilterResults results = new FilterResults();
                if (constraint != null)
                {
                    HttpURLConnection conn = null;
                    InputStream input = null;
                    try
                    {
                        URL url = new URL (server + constraint.toString());
                        conn = (HttpURLConnection) url.openConnection();
                        input = conn.getInputStream();
                        InputStreamReader reader = new InputStreamReader (input, "UTF-8");
                        BufferedReader buffer = new BufferedReader (reader, 8192);
                        StringBuilder builder = new StringBuilder();
                        String line;
                        while ((line = buffer.readLine()) != null)
                        {
                            builder.append (line);
                        }
                        JSONArray terms = new JSONArray (builder.toString());
                        ArrayList<String> suggestions = new ArrayList<>();
                        for (int ind = 0; ind < terms.length(); ind++)
                        {
                            String term = terms.getString (ind);
                            suggestions.add (term);
                        }
                        results.values = suggestions;
                        results.count = suggestions.size();
                        data = suggestions;
                    }
                    catch (Exception ex)
                    {
                        ex.printStackTrace();
                    }
                    finally
                    {
                        if (input != null)
                        {
                            try
                            {
                                input.close();
                            }
                            catch (Exception ex)
                            {
                                ex.printStackTrace();
                            }
                        }
                        if (conn != null) conn.disconnect();
                    }
                }
                return results;
            }

            @Override
            protected void publishResults (CharSequence constraint, FilterResults results)
            {
                if (results != null && results.count > 0)
                {
                    notifyDataSetChanged();
                }
                else notifyDataSetInvalidated();
            }
        };
    }

동일한 방식으로 사용하십시오.

public class MyActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        AutoCompleteTextView textView = (AutoCompleteTextView) findViewById (R.id.style);
        int layout = android.R.layout.simple_list_item_1;
        AutoCompleteAdapter adapter = new AutoCompleteAdapter (this, layout); 
        textView.setAdapter (adapter);
    }
}

Chu :보기의 모양을 사용자 지정하고 개체 래핑 해제에 대한 더 많은 제어를 얻으려면 다음을 수행하십시오.

    @Override
    public View getView (int position, View convertView, ViewGroup parent) {
        TextView originalView = (TextView) super.getView(position, convertView, parent); // Get the original view

        final LayoutInflater inflater = LayoutInflater.from(getContext());
        final TextView view = (TextView) inflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false);

        // Start tweaking
        view.setText(originalView.getText());
        view.setTextColor(R.color.black);  // also useful if you have a color scheme that makes the text show up white
        view.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10); // override the text size
        return view;
    }

private AutoCompleteUserAdapter userAdapter;
private AutoCompleteTextView actvName;
private ArrayList<SearchUserItem> arrayList;

actvName = findViewById(R.id.actvName);

actvName.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        actvName.setText(userAdapter.getItemNameAtPosition(position));
        actvName.setSelection(actvName.getText().toString().trim().length());
    }
});

actvName.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(final CharSequence s, int start, int before, int count) {
        if (actvName.isPerformingCompletion()) {
            // An item has been selected from the list. Ignore.
        } else {
            if (s.toString().toLowerCase().trim().length() >= 2) {
                getUserList(s.toString().toLowerCase().trim());
            }
        }
    }

    @Override
    public void afterTextChanged(Editable s) {

    }
});

private void getUserList(String searchText) {
    //Add data to your list after success of API call
    arrayList = new ArrayList<>();
    arrayList.addAll(YOUR_LIST);
    userAdapter = new AutoCompleteUserAdapter(context, R.layout.row_user, arrayList);
    getActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
            actvName.setAdapter(userAdapter);
            userAdapter.notifyDataSetChanged();
            actvName.showDropDown();
        }
    });        
}

AutoCompleteUserAdapter

/**
 * Created by Ketan Ramani on 11/07/2019.
 */
public class AutoCompleteUserAdapter extends ArrayAdapter<SearchUserItem> {

    private Context context;
    private int layoutResourceId;
    private ArrayList<SearchUserItem> arrayList;

    public AutoCompleteUserAdapter(Context context, int layoutResourceId, ArrayList<SearchUserItem> arrayList) {
        super(context, layoutResourceId, arrayList);
        this.context = context;
        this.layoutResourceId = layoutResourceId;
        this.arrayList = arrayList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        try {
            if (convertView == null) {
                convertView = LayoutInflater.from(parent.getContext()).inflate(layoutResourceId, parent, false);
            }

            SearchUserItem model = arrayList.get(position);

            AppCompatTextView tvUserName = convertView.findViewById(R.id.tvUserName);
            tvUserName.setText(model.getFullname());
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return convertView;
    }

    public String getItemNameAtPosition(int position) {
        return arrayList.get(position).getName();
    }

    public String getItemIDAtPosition(int position) {
        return arrayList.get(position).getId();
    }
}

참고URL : https://stackoverflow.com/questions/5023645/how-do-i-use-autocompletetextview-and-populate-it-with-data-from-a-web-api

반응형