AutoCompleteTextView的自定义过滤器在单击时返回错误的字符串

时间:2018-03-30 12:21:18

标签: android android-arrayadapter android-filterable android-filter custom-arrayadapter

我为ArrayAdapter为自定义Filter撰写了自定义AutoCompleteTextView。它会正确显示所有内容,但是当我过滤建议并单击某个项目时,它会显示所有项目显示时位于建议列表中此位置的项目的字符串。我制作了截图以澄清我的意思:

enter image description here

这是我的代码:

public class AutoCompleteCountryAdapter extends ArrayAdapter<CountryItem> {
private List<CountryItem> countryList;
private List<CountryItem> filteredCountryList = new ArrayList<>();

public AutoCompleteCountryAdapter(@NonNull Context context, @NonNull List<CountryItem> countryList) {
    super(context, 0, countryList);
    this.countryList = countryList;
}

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

@NonNull
@Override
public Filter getFilter() {
    return countryFilter;
}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    CountryItem countryItem = filteredCountryList.get(position);
    LayoutInflater inflater = LayoutInflater.from(getContext());

    if (convertView == null) {
        convertView = inflater.inflate(
                R.layout.country_autocomplete_row, parent, false
        );
    }

    TextView textViewName = convertView.findViewById(R.id.text_view_name);
    ImageView imageViewFlag = convertView.findViewById(R.id.image_view_flag);
    textViewName.setText(countryItem.getCountryName());
    imageViewFlag.setImageResource(countryItem.getFlagImage());

    return convertView;
}

private Filter countryFilter = new Filter() {

    private List<CountryItem> suggestions = new ArrayList<>();

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        suggestions.clear();
        FilterResults results = new FilterResults();

        if (constraint == null || constraint.length() == 0) {
            suggestions.addAll(countryList);
        } else {
            String filterPattern = constraint.toString().toLowerCase().trim();

            for (CountryItem item : countryList) {
                if (item.getCountryName().toLowerCase().contains(filterPattern)) {
                    suggestions.add(item);
                }
            }
        }
        results.values = suggestions;
        results.count = suggestions.size();
        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        filteredCountryList.clear();
        filteredCountryList.addAll((List) results.values);
        notifyDataSetChanged();
    }

    @Override
    public CharSequence convertResultToString(Object resultValue) {
        return ((CountryItem) resultValue).getCountryName();
    }
};
}

3 个答案:

答案 0 :(得分:0)

我提供了一个适配器类,它使用recylerview适配器来过滤用户联系人的用户联系人适配器。你可以根据代码改变你的要求..

public class InviteContactAdapter extends RecyclerView.Adapter<InviteContactAdapter.ItemViewHolder> implements Filterable {
private List<UserContact> mContactList = new ArrayList<>();
private List<UserContact> mContectFilter = new ArrayList<>();
private Context mContext;
private CustomFilter mFilter;
public List<String> mEmailList = new ArrayList<>();

public InviteContactAdapter(Context context, List<UserContact> mContactList) {
    mContext = context;
    this.mContactList = mContactList;
    this.mContectFilter = mContactList;
    mFilter = new CustomFilter();
}

public onItemClickListener onItemClickListener;

public void setOnItemClickListener(InviteContactAdapter.onItemClickListener onItemClickListener) {
    this.onItemClickListener = onItemClickListener;
}

@Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.invite_contact_row_layout, viewGroup, false);
    return new ItemViewHolder(view);
}

public interface onItemClickListener {
    void onClick(UserContact contact);
}

@Override
public Filter getFilter() {
    return mFilter;
}

@Override
public void onBindViewHolder(final ItemViewHolder itemViewHolder, int i) {
    final UserContact contact = mContectFilter.get(i);
    itemViewHolder.mTvUserNane.setText(contact.getUserName().trim());
    itemViewHolder.mTvUserEmail.setText(contact.getUserEmail().trim());
    if (contact.isSelect())
        itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
    else
        itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);


    itemViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            if (contact.isSelect()) {
                contact.setSelect(false);
                itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);
            } else {
                contact.setSelect(true);
                itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
            }
        }
    });

}

@Override
public int getItemCount() {
    return mContectFilter.size();
}

public class ItemViewHolder extends RecyclerView.ViewHolder {
    private TextView mTvUserNane, mTvUserEmail;
    private ImageView mIvSelect;

    public ItemViewHolder(View itemView) {
        super(itemView);
        mTvUserEmail = itemView.findViewById(R.id.icrlTvUserEmail);
        mTvUserNane = itemView.findViewById(R.id.icrlTvUserName);
        mIvSelect = itemView.findViewById(R.id.icrlIvSelect);
    }
}

public List<String> getEmail() {
    mEmailList.clear();
    for (UserContact contact : mContectFilter) {
        if (contact.isSelect()) {
            mEmailList.add(contact.getUserEmail());
        }
    }
    return mEmailList;
}

/**
 * this class for filter data.
 */
class CustomFilter extends Filter {

    @Override
    protected FilterResults performFiltering(CharSequence charSequence) {
        FilterResults results = new FilterResults();
        if (charSequence != null && charSequence.length() > 0) {
            ArrayList<UserContact> filters = new ArrayList<>();
            charSequence = charSequence.toString().toUpperCase();
            for (int i = 0; i < mContactList.size(); i++) {
                if (mContactList.get(i).getUserName().toUpperCase().contains(charSequence) || mContactList.get(i).getUserEmail().toUpperCase().contains(charSequence)) {
                    UserContact contact = new UserContact();
                    contact.setUserName(mContactList.get(i).getUserName());
                    contact.setUserEmail(mContactList.get(i).getUserEmail());
                    filters.add(contact);

                }
            }
            results.count = filters.size();
            results.values = filters;

        } else {
            results.count = mContactList.size();
            results.values = mContactList;
        }
        return results;
    }

    @Override
    protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
        mContectFilter = (ArrayList<UserContact>) filterResults.values;
        notifyDataSetChanged();
    }
}

}

答案 1 :(得分:0)

我解决了。 我不知道为什么这没有出现在我找到的任何教程中(包括Materialdoc),但你还必须覆盖适配器中的getItem,从过滤后的List中选择它的项目,而不是原始List:

<?php

$servername = "fdb18.awardspace.net";
$username = "2675740_infosys";
$password = "";
$dbname ="2675740_infosys";

// Create connection
$conn = mysqli_connect($servername, $username, $password,$dbname);

// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}


//echo "Connected successfully";

$username = $_POST['username'];
$password = $_POST['password'];


$sql = "SELECT * FROM login where username='$username'";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$user = $row['username'];
$pass = $row['password'];
$type = $row['type'];

  }
} else {
echo "Wrong Username or Password";
}


if($username == $user && $password == $pass && $type == 'admin') 
{

header('Location: LoggedHome.html');
} elseif ($username == $user && $password == $pass && $type == 'instructor')        {
header('Location: Instructor.html');
}else{
header('Location: Login.php');
}


$conn->close();
?>

答案 2 :(得分:0)

ArrayList<YourModel> arrayList = new ArrayList<>();
arrayList.addAll(yourList);

AutoCompleteAdapter autoCompleteAdapter = new AutoCompleteAdapter(context, arrayList);
autoCompleteTextView.setAdapter(brandAdapter);

autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        YourModel model = (YourModel) autoCompleteAdapter.getItem(position);
        autoCompleteTextView.setText(model.getText());
        autoCompleteTextView.setSelection(model.getText().length());
    }
});

AutoCompleteAdapter.java

public class AutoCompleteAdapter extends BaseAdapter implements Filterable {

    private Context context;
    private ArrayList<YourModel> originalList;
    private ArrayList<YourModel> suggestions = new ArrayList<>();
    private Filter filter = new CustomFilter();

    public AutoCompleteAdapter(Context context, ArrayList<YourModel> originalList) {
        this.context = context;
        this.originalList = originalList;
    }

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

            YourModel model = suggestions.get(position);

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

        return convertView;
    }

    @Override
    public Object getItem(int position) {
        return suggestions.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

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

    @Override
    public Filter getFilter() {
        return filter;
    }

    private class CustomFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            suggestions.clear();

            if (originalList != null && constraint != null) {
                for (int i = 0; i < originalList.size(); i++) {
                    if (originalList.get(i).getText().toLowerCase().contains(constraint.toString().toLowerCase().trim())) {
                        suggestions.add(originalList.get(i));
                    }
                }
            }
            FilterResults results = new FilterResults();
            results.values = suggestions;
            results.count = suggestions.size();

            return results;
        }

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