【问题标题】:How to use RecyclerView with AutoCompleteTextView in Android如何在 Android 中使用 RecyclerView 和 AutoCompleteTextView
【发布时间】:2020-06-25 19:54:39
【问题描述】:

我正在尝试将 recyclerview 与 autocompletetextview 一起使用,以在 autocompletetextview 的建议中显示特定的 UI,问题在于 autocompletetextview 中的项目膨胀它会像这样多次复制数据列表。

我尝试查看其他示例,但没有一个可以帮助我解决问题。

导航活动

public class NavigationActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {

private Toolbar toolbar;
private DrawerLayout drawerLayout;
private NavigationView navigationView;
private AppCompatTextView toolbarTitleTV;
private AppCompatAutoCompleteTextView toolbarSearchTV;
private MenuItem searchIcon;
private List<ListItemData> listItemDataList;


@Override
protected void onCreate(Bundle savedInstanceState) {

    AppCenter.start(getApplication(), "baec64eb-9311-42c1-a69b-d632caf0c5cb",
            Analytics.class, Crashes.class);

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_navigation);

    bindControls();
    bindListeners();
    toolbarSetting();
}

private void toolbarSetting() {
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayShowTitleEnabled(false);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_navigation);
}

private void bindListeners() {

    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawerLayout.addDrawerListener(toggle);
    toggle.syncState();

    navigationView.setNavigationItemSelectedListener(this);

    fillAutoCompleteList();
    AutoCompleteAdapter adapter = new AutoCompleteAdapter(this, listItemDataList);
    toolbarSearchTV.setAdapter(adapter);
}

private void fillAutoCompleteList(){
    listItemDataList = new ArrayList<>();
    for (int j = 0; j < 2; j++) {
        listItemDataList.add(new ListItemData(
                R.drawable.watch_subcategory_clip_1,
                "Casio Quartz",
                "By Casio",
                70));
    }
}

private void bindControls() {

    toolbar = findViewById(R.id.toolbarLayout);
    drawerLayout = findViewById(R.id.drawer_layout);
    navigationView = findViewById(R.id.nav_view);
    toolbarTitleTV = toolbar.findViewById(R.id.toolbarTitleTV);
    toolbarSearchTV = toolbar.findViewById(R.id.toolbarSearchTV);

    toolbar.bringToFront();
    toolbarTitleTV.setText(R.string.homeText);
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = findViewById(R.id.drawer_layout);
    if(toolbarSearchTV.getVisibility() == View.VISIBLE){
        searchIcon.setVisible(true);
        toolbarSearchTV.setVisibility(View.GONE);
        toolbarTitleTV.setVisibility(View.VISIBLE);
    }
    else if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    }
    else {
        finish();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.home_toolbar_menu, menu);
    searchIcon = menu.findItem(R.id.action_search);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    if (id == android.R.id.home){
        if(toolbarSearchTV.getVisibility() == View.VISIBLE){
            searchIcon.setVisible(true);
            toolbarSearchTV.setVisibility(View.GONE);
            toolbarTitleTV.setVisibility(View.VISIBLE);
        }
        drawerLayout.openDrawer(GravityCompat.START);
        return true;
    }
    else if (id == R.id.action_search){
        searchIcon.setVisible(false);
        toolbarSearchTV.setVisibility(View.VISIBLE);
        toolbarTitleTV.setVisibility(View.GONE);
    }
    else if (id == R.id.action_cart){
        startActivity(new Intent(getApplicationContext(), OrderStep1Activity.class));
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}

导航 XML (activity_navigation)

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 
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:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorBlack"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:clipToPadding="false">

    <include
        android:id="@+id/toolbarLayout"
        layout="@layout/app_toolbar_transparent" />

    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_drawer"
    app:menu="@menu/activity_drawer_menu" />

</android.support.v4.widget.DrawerLayout>

工具栏 XML (app_toolbar_transparent)

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:minHeight="?actionBarSize"
android:theme="@style/AppTheme.AppBarOverlay"
app:popupTheme="@style/AppTheme.PopupOverlay">

<android.support.v7.widget.AppCompatTextView
    android:id="@+id/toolbarTitleTV"
    style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
    android:layout_gravity="center"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/colorWhite"/>

<android.support.v7.widget.AppCompatAutoCompleteTextView
    android:id="@+id/toolbarSearchTV"
    style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/search_bar"
    android:drawableRight="@drawable/ic_search_red"
    android:hint="Search..."
    android:textColor="@color/colorLightBlack"
    android:padding="@dimen/_5sdp"
    android:completionThreshold="1"
    android:textColorHint="@color/colorGrayShade11"
    android:visibility="gone"/>

</android.support.v7.widget.Toolbar>

单项 XML (auto_complete_item)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorWhite"
android:layout_margin="@dimen/_10sdp">

<android.support.v7.widget.AppCompatImageView
    android:id="@+id/itemImageIV"
    android:layout_width="@dimen/_50sdp"
    android:layout_height="@dimen/_50sdp"
    android:src="@drawable/watch_clip_2"
    android:scaleType="centerCrop"/>

<android.support.v7.widget.AppCompatTextView
    android:id="@+id/itemNameTV"
    android:layout_toRightOf="@id/itemImageIV"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="AAAAAAAAAA"
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:textColor="@color/colorLightBlack"
    android:layout_marginLeft="@dimen/_5sdp" />

<android.support.v7.widget.AppCompatTextView
    android:id="@+id/itemDescTV"
    android:layout_toRightOf="@id/itemImageIV"
    android:layout_below="@id/itemNameTV"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="AAAAAAAAAA"
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:textColor="@color/colorGrayShade11"
    android:layout_marginLeft="@dimen/_5sdp" />

<View
    android:layout_marginTop="@dimen/_10sdp"
    android:layout_below="@id/itemImageIV"
    android:layout_width="match_parent"
    android:layout_height="@dimen/_1sdp"
    android:background="@color/colorGrayShade8"/>

</RelativeLayout>

RecyclerView XML (auto_complete_item_holder)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorWhite">

<android.support.v7.widget.RecyclerView
    android:id="@+id/autoCompleteRV"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

<android.support.v7.widget.AppCompatTextView
    android:id="@+id/showMoreTV"
    android:layout_centerHorizontal="true"
    android:layout_below="@id/autoCompleteRV"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Show More Results"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textColor="@color/colorMaroon"
    android:layout_marginTop="@dimen/_10sdp"
    android:layout_marginBottom="@dimen/_10sdp"/>

</RelativeLayout>

RecyclerView 适配器类(AutoCompleteRVAdapter)

package com.example.coolg.accessoriesapp.Adapter;

import android.app.Activity;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.AppCompatTextView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Spinner;

import com.example.coolg.accessoriesapp.Classes.ListItemData;
import com.example.coolg.accessoriesapp.R;

import java.util.List;

public class AutoCompleteRVAdapter extends RecyclerView.Adapter<AutoCompleteRVAdapter.AutoCompleteHolder> {

private Activity activity;
List<ListItemData> listItemDataList;

public AutoCompleteRVAdapter(Activity activity, List<ListItemData> listItemDataList) {
    this.activity = activity;
    this.listItemDataList = listItemDataList;
}

@Override
public AutoCompleteHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    LayoutInflater inflater = LayoutInflater.from(activity);
    View view = inflater.inflate(R.layout.auto_complete_item, viewGroup, false);
    return new AutoCompleteHolder(view);
}

@Override
public void onBindViewHolder(AutoCompleteHolder autoCompleteHolder, int position) {
    autoCompleteHolder.itemNameTV.setText(listItemDataList.get(position).getSubCategoryName());
    autoCompleteHolder.itemDescTV.setText(listItemDataList.get(position).getSubCategoryDescription());
    autoCompleteHolder.itemImageIV.setImageResource(listItemDataList.get(position).getSubCategoryImage());
}


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


public class AutoCompleteHolder extends RecyclerView.ViewHolder{

    AppCompatTextView itemNameTV, itemDescTV;
    AppCompatImageView itemImageIV;

    public AutoCompleteHolder(View cardView) {
        super(cardView);
        itemNameTV = cardView.findViewById(R.id.itemNameTV);
        itemDescTV = cardView.findViewById(R.id.itemDescTV);
        itemImageIV = cardView.findViewById(R.id.itemImageIV);
    }


}
}

自动完成适配器类(AutoCompleteRVAdapter)

import android.app.Activity;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.AppCompatTextView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;

import com.example.coolg.accessoriesapp.Activity.SearchListingActivity;
import com.example.coolg.accessoriesapp.Classes.ListItemData;
import com.example.coolg.accessoriesapp.R;

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

public class AutoCompleteAdapter extends ArrayAdapter<ListItemData> {

private Activity activity;
private List<ListItemData> listItemDataList;
private Boolean isInflated = false;

public AutoCompleteAdapter(Activity activity, List<ListItemData> listItemDataList){
    super(activity, R.layout.auto_complete_item_holder, listItemDataList);
    this.activity = activity;
    this.listItemDataList = listItemDataList;
}

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

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

    RecyclerView autoCompleteRV = convertView.findViewById(R.id.autoCompleteRV);
    AppCompatTextView showMoreTV = convertView.findViewById(R.id.showMoreTV);

    AutoCompleteRVAdapter adapter = new AutoCompleteRVAdapter(activity, listItemDataList);
    autoCompleteRV.setLayoutManager(new LinearLayoutManager(activity));
    autoCompleteRV.setAdapter(adapter);

    showMoreTV.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            activity.startActivity(new Intent(activity, SearchListingActivity.class));
        }
    });
    }

    return convertView;
}

private Filter itemFilter = new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults results = new FilterResults();
        List<ListItemData> suggestions = new ArrayList<>();

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

            for (ListItemData item : listItemDataList) {
                if (item.getSubCategoryName().toLowerCase().contains(filterPattern)) {
                    suggestions.add(item);
                }
            }
        }

        results.values = suggestions;
        results.count = suggestions.size();

        return results;
    }

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

    @Override
    public CharSequence convertResultToString(Object resultValue) {
        return ((ListItemData) resultValue).getSubCategoryName();
    }
};

}

我需要一个解决方案来帮助我扩展自定义 UI 建议对话框/框,其中包含“作为建议的项目列表”和“在建议底部查看更多结果文本视图”,我可以在其上设置 clicklistener 和列表的项目是可搜索的。

我已经能够使用“项目列表”和文本视图来扩充自定义 UI,但它们在自动完成文本视图中不断重复。

我还发现增加或减少自定义 UI 中项目列表的大小,增加或减少自动完成文本视图中建议的复制。

我当前的结果

我的预期结果

【问题讨论】:

    标签: android


    【解决方案1】:

    实际上的问题是,我们有一个基本适配器,在那个基本适配器中,我们有一个项目,其中包含一个回收器视图和一个文本视图,每当自动完成文本中的文本发生更改时,我都会写“ab”,然后当我写'a'然后添加并通知,然后我们写'b'另一个recyclerview被创建所以2个项目,每个都有一个recyclerview,我想出一个hack或解决方法,如果数据集大小> 0然后返回 1。或者返回 0。

        @Override
        public int getCount() {
            if(listItemDataList.size()>0)
            return 1;
            return 0;
        }
    

    希望对你有帮助。

    上述实现的一个问题是数据集大小随着每次搜索而减小。

    我重写了上面的这个函数并删除了加倍。

    【讨论】:

    • 感谢您抽出时间回复我的问题。由于这个问题是一年多前被问到的,我不得不四处更改代码的实现并删除 textview 以使其正常工作并得到客户的认可。我会尽快检查你的 hack 并尽快给你投票。 ?
    猜你喜欢
    • 2016-10-13
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多