简体   繁体   English

如何在 Android 中使用 RecyclerView 和 AutoCompleteTextView

[英]How to use RecyclerView with AutoCompleteTextView in Android

I am trying to use recyclerview with autocompletetextview to show a particular UI in the Suggestion of autocompletetextview the problem is on inflating the items in autocompletetextview it replicates the list of data multiple times like this.我正在尝试使用带有 autocompletetextview 的 recyclerview 在 autocompletetextview 的建议中显示特定的 UI 问题在于在 autocompletetextview 中膨胀项目,它像这样多次复制数据列表。

I tried to look other examples but none of them helps me to solve my problem.我尝试查看其他示例,但没有一个可以帮助我解决问题。

NavigationActivity导航活动

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

Navigation XML (activity_navigation)导航 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>

ToolBar XML (app_toolbar_transparent)工具栏 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>

Single Item XML (auto_complete_item)单项 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) 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 adapter class (AutoCompleteRVAdapter) 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);
    }


}
}

AutoComplete adapter class (AutoCompleteRVAdapter) AutoComplete 适配器类 (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();
    }
};

}

I need a solution which helps me inflate a custom UI suggestion dialog/box which contains 'list of items as suggestion' and a 'see more result textview at the bottom of suggestions' on which i can set a clicklistener and the list of items is searchable.我需要一个解决方案来帮助我扩充一个自定义 UI 建议对话框/框,其中包含“作为建议的项目列表”和“在建议的底部查看更多结果文本视图”,我可以在其中设置一个点击监听器,项目列表是可搜索。

I have been able to inflate the custom UI with 'list of items' and a textview' but they keep on repeating in the autocomplete textview.我已经能够使用“项目列表”和一个文本视图来扩展自定义 UI,但它们在自动完成文本视图中不断重复。

I also found out increasing or decreasing the size of list of items in the custom UI, increases or decreases the replication of suggestions in autocompletetextview.我还发现在自定义 UI 中增加或减少项目列表的大小,增加或减少自动完成文本视图中建议的复制。

My Current Result我目前的结果

我目前的结果

My Expected Result我的预期结果

我的预期结果

Actually the problem is that, we have a base adapter and in that base adapter we have a single item that contains, one recycler view and one textview, and whenever a text is changed in autocomplete text say I write "ab", then when I write 'a' then that is add and notified, and then we write 'b' another recyclerview is created so 2 items, each with one recyclerview, I come up with a hack or work around, if dataset size is >0 then return 1. Or return 0.实际上,问题是,我们有一个基本适配器,在该基本适配器中,我们有一个项目,其中包含一个回收器视图和一个文本视图,并且每当自动完成文本中的文本发生更改时说我写“ab”,然后当我写'a'然后添加并通知,然后我们写'b'另一个recyclerview被创建所以2个项目,每个都有一个recyclerview,我想出了一个黑客或解决方法,如果数据集大小>0然后返回1 . 或返回 0。

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

I hope it helps.我希望它有帮助。

One issue with above implementation is that dataset size decreases with each and every search.上述实现的一个问题是数据集大小随着每次搜索而减少。

I Overrided this above function and doubling was removed.我覆盖了上面的这个函数并删除了加倍。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM