使用搜索视图的特定标题(从 api 中获取)?
particular title(fetched from api) using searchview?
我想要这样的东西:
所以事情是,我真正想要的是当用户在搜索视图中键入特定主题名称(如果存在 in-app)时,它应该能够提供建议,如果找到它应该打开该主题 activity (就像 Facebook、Instagram 等搜索)..这些标题来自 API(我已经在其他活动中成功展示)..像这样:
..它的逻辑是什么???需要帮助...谢谢
所以我刚刚像这样在 XML 中包含了搜索视图-->
<SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Search Here"
android:iconifiedByDefault="false"
android:layout_alignParentTop="true"
android:background="@drawable/search_bar"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
android:pointerIcon="crosshair"
android:theme="@style/Widget.AppCompat.SearchView"
android:focusedByDefault="true"
/>
需要帮助..提前致谢.....
这是我的 json:
[{"id":"11","title":"TextView"},{"id":"10","title":"Edit Text"},{"id":"9","title":"ImageView"},{"id":"8","title":"Button "},{"id":"7","title":"CheckBox"},{"id":"6","title":"RadioButton & RadioGroup"},{"id":"5","title":"DatePicker"},{"id":"4","title":"TimePicker"},{"id":"3","title":"Switch"},{"id":"1","title":"Simple & Custom Toast"}]
这是我的activity:
public class StartLearning extends AppCompatActivity {
private RecyclerView recyclerView;
private SLAdapter slAdapter;
ProgressDialog progressDialog;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.startlearning_layout);
progressDialog = new ProgressDialog(StartLearning.this);
progressDialog.setMessage("Loading....");
progressDialog.show();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
/*Create handle for the RetrofitInstance interface*/
SLApiSevice service = SLApiClient.getRetrofitInstance().create(SLApiSevice.class);
Call<List<SlModel>> call = service.getMySlmodel();
call.enqueue(new Callback<List<SlModel>>() {
@Override
public void onResponse(Call<List<SlModel>> call, Response<List<SlModel>> response) {
progressDialog.dismiss();
generateDataList(response.body());
Log.e("hello", String.valueOf(response.body()));
}
@Override
public void onFailure(Call<List<SlModel>> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
}
}
private void generateDataList(List<SlModel> employeeList) {
recyclerView = findViewById(R.id.SLrecycle);
LinearLayoutManager manager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
slAdapter = new SLAdapter(getApplicationContext(),employeeList);
recyclerView.setAdapter(slAdapter);
}
适配器:
public class SLAdapter extends RecyclerView.Adapter<SLAdapter.CustomViewHolder> {
List<StartLearning.SlModel> Slmdel;
Context context;
public SLAdapter(Context context,List<StartLearning.SlModel> employees) {
this.Slmdel = employees;
this.context=context;
}
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.startlearning_item, parent, false);
return new CustomViewHolder(itemView);
}
@Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
// TipsModel employee = employees.get(position);
//// holder.employeeName.setText(employees.get(position).getTips());
holder.textView.setText(String.valueOf(position+1)+". ");
holder.employeeName.setText(Slmdel.get(position).getTitle());
}
@Override
public int getItemCount() {
return Slmdel.size();
//return (employees == null) ? 0 : employees.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView employeeName;
TextView textView;
public CustomViewHolder(View view) {
super(view);
employeeName = (TextView) view.findViewById(R.id.Sl2);
textView=view.findViewById(R.id.Sl1);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, NextSLactivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("title", Slmdel.get(getAdapterPosition()).getTitle());
intent.putExtra("idSLnext", Slmdel.get(getAdapterPosition()).getId());
//Log.e("ashwini",WAmdel.get(getAdapterPosition()).getId());
context.startActivity(intent);
}
});
}
}
点击项目(例如:textview)
activity:其中一项(例如:textview)
public class JavaFragment extends Fragment {
private RecyclerView recyclerView;
private NextSLJavaAdapter adapter;
private NextSLModel DescriptList;
ProgressDialog progressDialog;
public JavaFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.nextsl_layout, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Toolbar toolbar = (Toolbar) getView().findViewById(R.id. toolbar );
// setSupportActionBar( toolbar );
//if (getSupportActionBar() != null) {
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// getSupportActionBar().setDisplayShowHomeEnabled(true);
//}
progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage("Loading....");
progressDialog.show();
Intent intent = getActivity().getIntent();
String title = intent.getStringExtra("title");
//getSupportActionBar().setTitle(title);
String id = intent.getStringExtra("idSLnext");
Log.e("ashwini", String.valueOf(id));
/*Create handle for the RetrofitInstance interface*/
SLApiSevice service = SLApiClient.getRetrofitInstance().create(SLApiSevice.class);
Call<NextSLModel> call = service.getnextslmodel(id);
call.enqueue(new Callback<NextSLModel>() {
@Override
public void onResponse(Call<NextSLModel> call, Response<NextSLModel> response) {
progressDialog.dismiss();
DescriptList=response.body();
generateDataList(DescriptList);
}
@Override
public void onFailure(Call<NextSLModel> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(getContext(), "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
}
private void generateDataList(NextSLModel photoList) {
recyclerView = getView().findViewById(R.id.nextSLrecycle);
LinearLayoutManager manager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
adapter = new NextSLJavaAdapter(getContext(),photoList);
recyclerView.setAdapter(adapter);
}
}
适配器:
public class NextSLJavaAdapter extends RecyclerView.Adapter<NextSLJavaAdapter.CustomViewHolder> {
NextSLModel Slmdel;
Context context;
public NextSLJavaAdapter(Context context, NextSLModel employees) {
this.Slmdel = employees;
this.context = context;
}
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.nextsl_item, parent, false);
return new CustomViewHolder(itemView);
}
@Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
// TipsModel employee = employees.get(position);
//// holder.employeeName.setText(employees.get(position).getTips());
///////// holder.textView.setText(String.valueOf(position + 1) + ". ");
holder.employeeName.setText(Slmdel.getJava());
Log.e("sl",Slmdel.getJava());
}
@Override
public int getItemCount() {
return 1;
//return (employees == null) ? 0 : employees.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView employeeName;
TextView textView;
public CustomViewHolder(View view) {
super(view);
employeeName = (TextView) view.findViewById(R.id.detailsStartLearning);
textView = view.findViewById(R.id.Sl1);}}}
看看这个搜索activity:
public class Search extends AppCompatActivity {
SearchView searchView;
RecyclerView recyclerView;
SearchAdapter slAdapter;
List<StartLearning.SlModel> movieList;
ChipGroup chipGroup;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
searchView=findViewById(R.id.searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
searchForResults(newText);
return false;
}
});
//new code
chipGroup = findViewById(R.id. chipGroup);
searchView.onActionViewExpanded();
searchView.setIconified(true);
}
public void searchForResults(String search){
//here make an api call to get the results, complete the code here
SLApiSevice service = SLApiClient.getRetrofitInstance().create(SLApiSevice.class);
retrofit2.Call<List<StartLearning.SlModel>> call = service.getMySlmodel();
call.enqueue(new Callback<List<StartLearning.SlModel>>() {
@Override
public void onResponse(retrofit2.Call<List<StartLearning.SlModel>> call, Response<List<StartLearning.SlModel>> response) {
List<StartLearning.SlModel> list = response.body();
generateDataList(list);
addChips(list);
Log.d("TAG","Response = "+movieList);
slAdapter.setMovieList(getApplicationContext(),movieList);
}
@Override
public void onFailure(retrofit2.Call<List<StartLearning.SlModel>> call, Throwable t) {
Log.d("TAG","Response = "+t.toString());
}
});
}
private void generateDataList(List<StartLearning.SlModel> employeeList) {
recyclerView = findViewById(R.id.recyclerview);
LinearLayoutManager manager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
slAdapter = new SearchAdapter(getApplicationContext(),employeeList);
recyclerView.setAdapter(slAdapter);
}
public void addChips(List<StartLearning.SlModel> searchItems){
for (StartLearning.SlModel item : searchItems) {
Chip mChip = (Chip) this.getLayoutInflater().inflate(R.layout.item_chips, null, false);
mChip.setText(item.getTitle());
int paddingDp = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 10,
getResources().getDisplayMetrics()
);
mChip.setPadding(paddingDp, 0, paddingDp, 0);
mChip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Handle the click here
}
});
chipGroup.removeAllViews();
chipGroup.addView(mChip);
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
}
xml 搜索:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" >
</androidx.appcompat.widget.Toolbar>
<SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Search Here"
android:iconifiedByDefault="false"
android:layout_alignParentTop="true"
android:background="@drawable/search_bar"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
android:pointerIcon="crosshair"
android:theme="@style/Widget.AppCompat.SearchView"
android:focusedByDefault="true"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:id="@+id/chipGroup"
app:chipSpacing="25dp"/>
</LinearLayout>
搜索适配器:
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.CustomViewHolder> implements Filterable {
List<StartLearning.SlModel> Slmdel;
List<StartLearning.SlModel> Slmdel1;
Context context;
public SearchAdapter() {
}
public void setMovieList(Context context, final List<StartLearning.SlModel> movieList){
this.context = context;
if(this.Slmdel == null){
this.Slmdel = movieList;
this.Slmdel1 = movieList;
notifyItemChanged(0, Slmdel1.size());
} else {
final DiffUtil.DiffResult result = DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return SearchAdapter.this.Slmdel.size();
}
@Override
public int getNewListSize() {
// return movieList.size();
return (movieList == null) ? 0 : movieList.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return SearchAdapter.this.Slmdel.get(oldItemPosition).getTitle() == movieList.get(newItemPosition).getTitle();
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
StartLearning.SlModel newMovie = SearchAdapter.this.Slmdel.get(oldItemPosition);
StartLearning.SlModel oldMovie = movieList.get(newItemPosition);
return newMovie.getTitle() == oldMovie.getTitle() ;
}
});
this.Slmdel = movieList;
this.Slmdel1 = movieList;
result.dispatchUpdatesTo(this);
}
}
public SearchAdapter(Context context,List<StartLearning.SlModel> employees) {
this.Slmdel = employees;
this.context=context;
}
@Override
public SearchAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.startlearning_item, parent, false);
return new SearchAdapter.CustomViewHolder(itemView);
}
@Override
public void onBindViewHolder(SearchAdapter.CustomViewHolder holder, int position) {
holder.employeeName.setText(Slmdel.get(position).getTitle());
}
@Override
public int getItemCount() {
if(Slmdel != null){
return Slmdel1.size();
} else {
return 0;
}
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final List<StartLearning.SlModel> results = new ArrayList<StartLearning.SlModel>();
if (Slmdel1 == null)
Slmdel1 = Slmdel;
if (constraint != null) {
if (Slmdel1 != null & Slmdel1.size() > 0) {
for (final StartLearning.SlModel g : Slmdel1) {
if (g.getTitle().toLowerCase().contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
Slmdel1 = (ArrayList<StartLearning.SlModel>) results.values;
notifyDataSetChanged();
}
};}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView employeeName;
TextView textView;
public CustomViewHolder(View view) {
super(view);
employeeName = (TextView) view.findViewById(R.id.Sl2);
textView = view.findViewById(R.id.Sl1);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, NextSLactivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("title", Slmdel.get(getAdapterPosition()).getTitle());
intent.putExtra("idSLnext", Slmdel.get(getAdapterPosition()).getId());
//Log.e("ashwini",WAmdel.get(getAdapterPosition()).getId());
context.startActivity(intent);
}
});
}
}
}
android 中有一个新的 Chip Material 组件。可以用来满足要求。我相信你目前正在使用一些 recyclerview 来显示那些搜索项目,而不是使用这个使用 ChiGroup 来保存那些 values.a
下面是一些示例代码
首先将此添加到您的 gradle 以使用外部库依赖项
implementation 'com.google.android.material:material:1.0.0-alpha1'
然后在搜索视图下方的所需布局中放置此 xml 代码。
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:id="@+id/chipGroup"
app:chipSpacing="25dp"/>
ChipGroup
将包含 Chip
个将动态添加的项目。
所以现在在您的搜索中 activity/fragment 只需获取此布局组的参考即可。
public class Search extends AppCompatActivity {
SearchView searchView;
ChipGroup chipGroup;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
searchView = findViewById(R.id.searchView);
//new code
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
searchForResults(newText);
return false;
}
});
//new code
chipGroup = findViewById(R.id. chipGroup);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() ==android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
//new code
public void searchForResults(String search){
//here make an api call to get the results, complete the code here
call.enqueue(new Callback<List<StartLearning.SlModel>>() {
@Override
public void onResponse(retrofit2.Call<List<StartLearning.SlModel>> call, Response<List<StartLearning.SlModel>> response) {
List<StartLearning.SlModel> list = response.body();
//after getting the results pass to addChips()
addChips(list)
Log.d("TAG","Response = "+movieList);
}
@Override
public void onFailure(retrofit2.Call<List<StartLearning.SlModel>> call, Throwable t) {
Log.d("TAG","Response = "+t.toString());
}
});
}
//just call this when you get the search result from the api with your custom model and where ever it is applicable.
public void addChips(List<StartLearning.SlModel> searchItems){
for (StartLearning.SlModel item : searchItems) {
Chip mChip = (Chip) this.getLayoutInflater().inflate(R.layout.item_chip, null, false);
mChip.setText(item.title);
int paddingDp = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 10,
getResources().getDisplayMetrics()
);
mChip.setPadding(paddingDp, 0, paddingDp, 0);
mChip.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// Handle the click here
}
});
chipGroup.removeAllViews();
chipGroup.addView(mChip);
}
}
}
在搜索中找不到相关代码activity举个例子。但总体思路如下。
1) 您添加一个 ChipGroup 来保存将在您的搜索视图中动态添加的 Chip 视图 xml。
2) 用户搜索一些东西,你得到 api 响应,然后你创建了一个基于模型的列表。
3) 然后您逐个遍历列表并创建动态筹码。
4) 但首先创建一个包含以下内容的 item_chip.xml 文件。
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:id=@+id/smallChip
style="@style/Widget.MaterialComponents.Chip.Choice"
android:textAppearance="?android:attr/textAppearance"
android:textColor="@color/secondaryTextColor"
app:chipBackgroundColor="@color/colorAccent" />
5) 现在我们将 inflate 这个布局文件并将其添加到我们之前收到的 for 循环中的 ChipGroup。
6) 所以示例代码是这样将动态芯片添加到 ChipGroup。为简单起见,我在这里使用字符串作为搜索项,您可以在此处使用自己的模型。
public void addChips(ArrayList<String> searchItems){
for (String item : searchItems) {
Chip mChip = (Chip) this.getLayoutInflater().inflate(R.layout.item_chip, null, false);
mChip.setText(item);
int paddingDp = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 10,
getResources().getDisplayMetrics()
);
mChip.setPadding(paddingDp, 0, paddingDp, 0);
mChip.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// Handle the click here
}
});
chipGroup.addView(mChip);
}
}
现在我们刚刚将芯片动态添加到我们之前在搜索视图布局中声明的 chipGroup 中。但这也可以使用 Recyclerview 而不是使用 ChipGropup 来完成,只需在 recyclerview 项目中添加 Chip View 并获取参考并设置文本,就像您对文本视图所做的那样,除了适配器和项目布局之外没有任何改变。
编辑:2020 年 4 月 1 日
将 ChipGrop 放入下面的 XML 文件中进行搜索。这个想法是搜索视图输入框将位于顶部,搜索建议将位于搜索框下方,以便在同一屏幕上提供不断变化的搜索结果。所以在 Search activity 本身中调用与搜索相关的 API 调用,并将结果传递给示例方法 addChips() 我上面已经提到了。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Search Here"
android:iconifiedByDefault="false"
android:layout_alignParentTop="true"
android:background="@drawable/search_bar"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
android:pointerIcon="crosshair"
android:theme="@style/Widget.AppCompat.SearchView"
android:focusedByDefault="true"/>
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:id="@+id/chipGroup"
app:chipSpacing="25dp"/>
</LinearLayout>
有关更多信息,请阅读以下博客:
你可以在花一点时间后做这个 Chip View 按钮,我发现这个库更适合你的情况,因为你试图通过搜索视图实现。
所以试试这个:
将此行添加到您的模块级别 build.gradle:
dependencies {
implementation "com.hootsuite.android:nachos:1.1.1"
}
在您的 xml 布局中包含一个 NachoTextView,如下所示:
<com.hootsuite.nachos.NachoTextView
android:id="@+id/nacho_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
您可以在 github 上查看完整内容,也可以通过搜索视图查找此答案来实现:
将此库添加到您的 gradle
implementation 'com.google.android.material:material:1.2.0-alpha02'
将 AppTheme
的父级更改为 values/styles.xml
中的 Theme.MaterialComponents.Light.NoActionBar
。就像这样
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
现在您需要将 edittext
和 chipgroup
添加到您的 xml
。就像这样
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/search_edittext"/>
<com.google.android.material.chip.ChipGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/chipgroup"
app:singleSelection="true"
>
</com.google.android.material.chip.ChipGroup>
现在创建 method
添加 chip
到 chipgroup
void setChip(List<String> list)
{
chipgroup.removeAllViews();
for (String item : list)
{
Chip chip =new Chip(this);
chip.setText(item);
// necessary to get single selection working
chip.setCheckable(true);
chip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("OnCheckedChangeListener", "Called");
}
});
//on chip click
chipgroup.addView(chip);
}
}
现在将 addTextChangedListener
添加到您的 edittext
search_edittext.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
List<String> tem=new ArrayList();
for (String item : list)
{
if (item.toString().toLowerCase().contains(s.toString().toLowerCase()))
tem.add(item);
}
setChip(tem);
}
});
这就完成了。
您可以使用 recyclerview 和适配器获得与您的搜索查询相关的建议。
[1] 创建新的 adapter 并把你的 setMovieList() 和 getFilter() 进去。
[2] 将该适配器设置为 recyclerview of suggestions 并在您获得建议数组列表时通知适配器。
检查下面的代码
public void onResponse(retrofit2.Call<List<StartLearning.SlModel>> call, Response<List<StartLearning.SlModel>> response) {
movieList = response.body();
if(movieList.size()!=0){
tvSuggestions.setVisibility(View.VISIBLE);
suggestionAdapter=new SuggestionAdapter(Search.this,movieList);
recyclerViewSuggestions.setAdapter(suggestionAdapter);
Log.e("TAG", "onResponse: size of movielist "+movieList);
suggestionAdapter.getFilter().filter(query);
suggestionAdapter.notifyDataSetChanged();
suggestionAdapter.setMovieList(Search.this,movieList);
}
else{
tvSuggestions.setVisibility(View.VISIBLE);
tvSuggestions.setText("No Suggestions Found");
}
/*generateDataList(movieList);
Log.d("TAG","Response = "+movieList);
slAdapter.setMovieList(getApplicationContext(),movieList);*/
}
我想要这样的东西:
所以事情是,我真正想要的是当用户在搜索视图中键入特定主题名称(如果存在 in-app)时,它应该能够提供建议,如果找到它应该打开该主题 activity (就像 Facebook、Instagram 等搜索)..这些标题来自 API(我已经在其他活动中成功展示)..像这样:
..它的逻辑是什么???需要帮助...谢谢
所以我刚刚像这样在 XML 中包含了搜索视图-->
<SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Search Here"
android:iconifiedByDefault="false"
android:layout_alignParentTop="true"
android:background="@drawable/search_bar"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
android:pointerIcon="crosshair"
android:theme="@style/Widget.AppCompat.SearchView"
android:focusedByDefault="true"
/>
需要帮助..提前致谢.....
这是我的 json:
[{"id":"11","title":"TextView"},{"id":"10","title":"Edit Text"},{"id":"9","title":"ImageView"},{"id":"8","title":"Button "},{"id":"7","title":"CheckBox"},{"id":"6","title":"RadioButton & RadioGroup"},{"id":"5","title":"DatePicker"},{"id":"4","title":"TimePicker"},{"id":"3","title":"Switch"},{"id":"1","title":"Simple & Custom Toast"}]
这是我的activity:
public class StartLearning extends AppCompatActivity {
private RecyclerView recyclerView;
private SLAdapter slAdapter;
ProgressDialog progressDialog;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.startlearning_layout);
progressDialog = new ProgressDialog(StartLearning.this);
progressDialog.setMessage("Loading....");
progressDialog.show();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
/*Create handle for the RetrofitInstance interface*/
SLApiSevice service = SLApiClient.getRetrofitInstance().create(SLApiSevice.class);
Call<List<SlModel>> call = service.getMySlmodel();
call.enqueue(new Callback<List<SlModel>>() {
@Override
public void onResponse(Call<List<SlModel>> call, Response<List<SlModel>> response) {
progressDialog.dismiss();
generateDataList(response.body());
Log.e("hello", String.valueOf(response.body()));
}
@Override
public void onFailure(Call<List<SlModel>> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
}
}
private void generateDataList(List<SlModel> employeeList) {
recyclerView = findViewById(R.id.SLrecycle);
LinearLayoutManager manager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
slAdapter = new SLAdapter(getApplicationContext(),employeeList);
recyclerView.setAdapter(slAdapter);
}
适配器:
public class SLAdapter extends RecyclerView.Adapter<SLAdapter.CustomViewHolder> {
List<StartLearning.SlModel> Slmdel;
Context context;
public SLAdapter(Context context,List<StartLearning.SlModel> employees) {
this.Slmdel = employees;
this.context=context;
}
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.startlearning_item, parent, false);
return new CustomViewHolder(itemView);
}
@Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
// TipsModel employee = employees.get(position);
//// holder.employeeName.setText(employees.get(position).getTips());
holder.textView.setText(String.valueOf(position+1)+". ");
holder.employeeName.setText(Slmdel.get(position).getTitle());
}
@Override
public int getItemCount() {
return Slmdel.size();
//return (employees == null) ? 0 : employees.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView employeeName;
TextView textView;
public CustomViewHolder(View view) {
super(view);
employeeName = (TextView) view.findViewById(R.id.Sl2);
textView=view.findViewById(R.id.Sl1);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, NextSLactivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("title", Slmdel.get(getAdapterPosition()).getTitle());
intent.putExtra("idSLnext", Slmdel.get(getAdapterPosition()).getId());
//Log.e("ashwini",WAmdel.get(getAdapterPosition()).getId());
context.startActivity(intent);
}
});
}
}
点击项目(例如:textview)
activity:其中一项(例如:textview)
public class JavaFragment extends Fragment {
private RecyclerView recyclerView;
private NextSLJavaAdapter adapter;
private NextSLModel DescriptList;
ProgressDialog progressDialog;
public JavaFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.nextsl_layout, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Toolbar toolbar = (Toolbar) getView().findViewById(R.id. toolbar );
// setSupportActionBar( toolbar );
//if (getSupportActionBar() != null) {
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// getSupportActionBar().setDisplayShowHomeEnabled(true);
//}
progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage("Loading....");
progressDialog.show();
Intent intent = getActivity().getIntent();
String title = intent.getStringExtra("title");
//getSupportActionBar().setTitle(title);
String id = intent.getStringExtra("idSLnext");
Log.e("ashwini", String.valueOf(id));
/*Create handle for the RetrofitInstance interface*/
SLApiSevice service = SLApiClient.getRetrofitInstance().create(SLApiSevice.class);
Call<NextSLModel> call = service.getnextslmodel(id);
call.enqueue(new Callback<NextSLModel>() {
@Override
public void onResponse(Call<NextSLModel> call, Response<NextSLModel> response) {
progressDialog.dismiss();
DescriptList=response.body();
generateDataList(DescriptList);
}
@Override
public void onFailure(Call<NextSLModel> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(getContext(), "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
}
private void generateDataList(NextSLModel photoList) {
recyclerView = getView().findViewById(R.id.nextSLrecycle);
LinearLayoutManager manager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
adapter = new NextSLJavaAdapter(getContext(),photoList);
recyclerView.setAdapter(adapter);
}
}
适配器:
public class NextSLJavaAdapter extends RecyclerView.Adapter<NextSLJavaAdapter.CustomViewHolder> {
NextSLModel Slmdel;
Context context;
public NextSLJavaAdapter(Context context, NextSLModel employees) {
this.Slmdel = employees;
this.context = context;
}
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.nextsl_item, parent, false);
return new CustomViewHolder(itemView);
}
@Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
// TipsModel employee = employees.get(position);
//// holder.employeeName.setText(employees.get(position).getTips());
///////// holder.textView.setText(String.valueOf(position + 1) + ". ");
holder.employeeName.setText(Slmdel.getJava());
Log.e("sl",Slmdel.getJava());
}
@Override
public int getItemCount() {
return 1;
//return (employees == null) ? 0 : employees.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView employeeName;
TextView textView;
public CustomViewHolder(View view) {
super(view);
employeeName = (TextView) view.findViewById(R.id.detailsStartLearning);
textView = view.findViewById(R.id.Sl1);}}}
看看这个搜索activity:
public class Search extends AppCompatActivity {
SearchView searchView;
RecyclerView recyclerView;
SearchAdapter slAdapter;
List<StartLearning.SlModel> movieList;
ChipGroup chipGroup;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
searchView=findViewById(R.id.searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
searchForResults(newText);
return false;
}
});
//new code
chipGroup = findViewById(R.id. chipGroup);
searchView.onActionViewExpanded();
searchView.setIconified(true);
}
public void searchForResults(String search){
//here make an api call to get the results, complete the code here
SLApiSevice service = SLApiClient.getRetrofitInstance().create(SLApiSevice.class);
retrofit2.Call<List<StartLearning.SlModel>> call = service.getMySlmodel();
call.enqueue(new Callback<List<StartLearning.SlModel>>() {
@Override
public void onResponse(retrofit2.Call<List<StartLearning.SlModel>> call, Response<List<StartLearning.SlModel>> response) {
List<StartLearning.SlModel> list = response.body();
generateDataList(list);
addChips(list);
Log.d("TAG","Response = "+movieList);
slAdapter.setMovieList(getApplicationContext(),movieList);
}
@Override
public void onFailure(retrofit2.Call<List<StartLearning.SlModel>> call, Throwable t) {
Log.d("TAG","Response = "+t.toString());
}
});
}
private void generateDataList(List<StartLearning.SlModel> employeeList) {
recyclerView = findViewById(R.id.recyclerview);
LinearLayoutManager manager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
slAdapter = new SearchAdapter(getApplicationContext(),employeeList);
recyclerView.setAdapter(slAdapter);
}
public void addChips(List<StartLearning.SlModel> searchItems){
for (StartLearning.SlModel item : searchItems) {
Chip mChip = (Chip) this.getLayoutInflater().inflate(R.layout.item_chips, null, false);
mChip.setText(item.getTitle());
int paddingDp = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 10,
getResources().getDisplayMetrics()
);
mChip.setPadding(paddingDp, 0, paddingDp, 0);
mChip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Handle the click here
}
});
chipGroup.removeAllViews();
chipGroup.addView(mChip);
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
}
xml 搜索:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" >
</androidx.appcompat.widget.Toolbar>
<SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Search Here"
android:iconifiedByDefault="false"
android:layout_alignParentTop="true"
android:background="@drawable/search_bar"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
android:pointerIcon="crosshair"
android:theme="@style/Widget.AppCompat.SearchView"
android:focusedByDefault="true"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:id="@+id/chipGroup"
app:chipSpacing="25dp"/>
</LinearLayout>
搜索适配器:
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.CustomViewHolder> implements Filterable {
List<StartLearning.SlModel> Slmdel;
List<StartLearning.SlModel> Slmdel1;
Context context;
public SearchAdapter() {
}
public void setMovieList(Context context, final List<StartLearning.SlModel> movieList){
this.context = context;
if(this.Slmdel == null){
this.Slmdel = movieList;
this.Slmdel1 = movieList;
notifyItemChanged(0, Slmdel1.size());
} else {
final DiffUtil.DiffResult result = DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return SearchAdapter.this.Slmdel.size();
}
@Override
public int getNewListSize() {
// return movieList.size();
return (movieList == null) ? 0 : movieList.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return SearchAdapter.this.Slmdel.get(oldItemPosition).getTitle() == movieList.get(newItemPosition).getTitle();
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
StartLearning.SlModel newMovie = SearchAdapter.this.Slmdel.get(oldItemPosition);
StartLearning.SlModel oldMovie = movieList.get(newItemPosition);
return newMovie.getTitle() == oldMovie.getTitle() ;
}
});
this.Slmdel = movieList;
this.Slmdel1 = movieList;
result.dispatchUpdatesTo(this);
}
}
public SearchAdapter(Context context,List<StartLearning.SlModel> employees) {
this.Slmdel = employees;
this.context=context;
}
@Override
public SearchAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.startlearning_item, parent, false);
return new SearchAdapter.CustomViewHolder(itemView);
}
@Override
public void onBindViewHolder(SearchAdapter.CustomViewHolder holder, int position) {
holder.employeeName.setText(Slmdel.get(position).getTitle());
}
@Override
public int getItemCount() {
if(Slmdel != null){
return Slmdel1.size();
} else {
return 0;
}
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final List<StartLearning.SlModel> results = new ArrayList<StartLearning.SlModel>();
if (Slmdel1 == null)
Slmdel1 = Slmdel;
if (constraint != null) {
if (Slmdel1 != null & Slmdel1.size() > 0) {
for (final StartLearning.SlModel g : Slmdel1) {
if (g.getTitle().toLowerCase().contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
Slmdel1 = (ArrayList<StartLearning.SlModel>) results.values;
notifyDataSetChanged();
}
};}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView employeeName;
TextView textView;
public CustomViewHolder(View view) {
super(view);
employeeName = (TextView) view.findViewById(R.id.Sl2);
textView = view.findViewById(R.id.Sl1);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, NextSLactivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("title", Slmdel.get(getAdapterPosition()).getTitle());
intent.putExtra("idSLnext", Slmdel.get(getAdapterPosition()).getId());
//Log.e("ashwini",WAmdel.get(getAdapterPosition()).getId());
context.startActivity(intent);
}
});
}
}
}
android 中有一个新的 Chip Material 组件。可以用来满足要求。我相信你目前正在使用一些 recyclerview 来显示那些搜索项目,而不是使用这个使用 ChiGroup 来保存那些 values.a
下面是一些示例代码
首先将此添加到您的 gradle 以使用外部库依赖项
implementation 'com.google.android.material:material:1.0.0-alpha1'
然后在搜索视图下方的所需布局中放置此 xml 代码。
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:id="@+id/chipGroup"
app:chipSpacing="25dp"/>
ChipGroup
将包含 Chip
个将动态添加的项目。
所以现在在您的搜索中 activity/fragment 只需获取此布局组的参考即可。
public class Search extends AppCompatActivity {
SearchView searchView;
ChipGroup chipGroup;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
searchView = findViewById(R.id.searchView);
//new code
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
searchForResults(newText);
return false;
}
});
//new code
chipGroup = findViewById(R.id. chipGroup);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() ==android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
//new code
public void searchForResults(String search){
//here make an api call to get the results, complete the code here
call.enqueue(new Callback<List<StartLearning.SlModel>>() {
@Override
public void onResponse(retrofit2.Call<List<StartLearning.SlModel>> call, Response<List<StartLearning.SlModel>> response) {
List<StartLearning.SlModel> list = response.body();
//after getting the results pass to addChips()
addChips(list)
Log.d("TAG","Response = "+movieList);
}
@Override
public void onFailure(retrofit2.Call<List<StartLearning.SlModel>> call, Throwable t) {
Log.d("TAG","Response = "+t.toString());
}
});
}
//just call this when you get the search result from the api with your custom model and where ever it is applicable.
public void addChips(List<StartLearning.SlModel> searchItems){
for (StartLearning.SlModel item : searchItems) {
Chip mChip = (Chip) this.getLayoutInflater().inflate(R.layout.item_chip, null, false);
mChip.setText(item.title);
int paddingDp = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 10,
getResources().getDisplayMetrics()
);
mChip.setPadding(paddingDp, 0, paddingDp, 0);
mChip.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// Handle the click here
}
});
chipGroup.removeAllViews();
chipGroup.addView(mChip);
}
}
}
在搜索中找不到相关代码activity举个例子。但总体思路如下。
1) 您添加一个 ChipGroup 来保存将在您的搜索视图中动态添加的 Chip 视图 xml。 2) 用户搜索一些东西,你得到 api 响应,然后你创建了一个基于模型的列表。 3) 然后您逐个遍历列表并创建动态筹码。
4) 但首先创建一个包含以下内容的 item_chip.xml 文件。
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:id=@+id/smallChip
style="@style/Widget.MaterialComponents.Chip.Choice"
android:textAppearance="?android:attr/textAppearance"
android:textColor="@color/secondaryTextColor"
app:chipBackgroundColor="@color/colorAccent" />
5) 现在我们将 inflate 这个布局文件并将其添加到我们之前收到的 for 循环中的 ChipGroup。
6) 所以示例代码是这样将动态芯片添加到 ChipGroup。为简单起见,我在这里使用字符串作为搜索项,您可以在此处使用自己的模型。
public void addChips(ArrayList<String> searchItems){
for (String item : searchItems) {
Chip mChip = (Chip) this.getLayoutInflater().inflate(R.layout.item_chip, null, false);
mChip.setText(item);
int paddingDp = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 10,
getResources().getDisplayMetrics()
);
mChip.setPadding(paddingDp, 0, paddingDp, 0);
mChip.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// Handle the click here
}
});
chipGroup.addView(mChip);
}
}
现在我们刚刚将芯片动态添加到我们之前在搜索视图布局中声明的 chipGroup 中。但这也可以使用 Recyclerview 而不是使用 ChipGropup 来完成,只需在 recyclerview 项目中添加 Chip View 并获取参考并设置文本,就像您对文本视图所做的那样,除了适配器和项目布局之外没有任何改变。
编辑:2020 年 4 月 1 日
将 ChipGrop 放入下面的 XML 文件中进行搜索。这个想法是搜索视图输入框将位于顶部,搜索建议将位于搜索框下方,以便在同一屏幕上提供不断变化的搜索结果。所以在 Search activity 本身中调用与搜索相关的 API 调用,并将结果传递给示例方法 addChips() 我上面已经提到了。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Search Here"
android:iconifiedByDefault="false"
android:layout_alignParentTop="true"
android:background="@drawable/search_bar"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
android:pointerIcon="crosshair"
android:theme="@style/Widget.AppCompat.SearchView"
android:focusedByDefault="true"/>
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:id="@+id/chipGroup"
app:chipSpacing="25dp"/>
</LinearLayout>
有关更多信息,请阅读以下博客:
你可以在花一点时间后做这个 Chip View 按钮,我发现这个库更适合你的情况,因为你试图通过搜索视图实现。
所以试试这个:
将此行添加到您的模块级别 build.gradle:
dependencies {
implementation "com.hootsuite.android:nachos:1.1.1"
}
在您的 xml 布局中包含一个 NachoTextView,如下所示:
<com.hootsuite.nachos.NachoTextView
android:id="@+id/nacho_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
您可以在 github 上查看完整内容,也可以通过搜索视图查找此答案来实现:
将此库添加到您的 gradle
implementation 'com.google.android.material:material:1.2.0-alpha02'
将 AppTheme
的父级更改为 values/styles.xml
中的 Theme.MaterialComponents.Light.NoActionBar
。就像这样
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
现在您需要将 edittext
和 chipgroup
添加到您的 xml
。就像这样
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/search_edittext"/>
<com.google.android.material.chip.ChipGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/chipgroup"
app:singleSelection="true"
>
</com.google.android.material.chip.ChipGroup>
现在创建 method
添加 chip
到 chipgroup
void setChip(List<String> list)
{
chipgroup.removeAllViews();
for (String item : list)
{
Chip chip =new Chip(this);
chip.setText(item);
// necessary to get single selection working
chip.setCheckable(true);
chip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("OnCheckedChangeListener", "Called");
}
});
//on chip click
chipgroup.addView(chip);
}
}
现在将 addTextChangedListener
添加到您的 edittext
search_edittext.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
List<String> tem=new ArrayList();
for (String item : list)
{
if (item.toString().toLowerCase().contains(s.toString().toLowerCase()))
tem.add(item);
}
setChip(tem);
}
});
这就完成了。
您可以使用 recyclerview 和适配器获得与您的搜索查询相关的建议。
[1] 创建新的 adapter 并把你的 setMovieList() 和 getFilter() 进去。
[2] 将该适配器设置为 recyclerview of suggestions 并在您获得建议数组列表时通知适配器。
检查下面的代码
public void onResponse(retrofit2.Call<List<StartLearning.SlModel>> call, Response<List<StartLearning.SlModel>> response) {
movieList = response.body();
if(movieList.size()!=0){
tvSuggestions.setVisibility(View.VISIBLE);
suggestionAdapter=new SuggestionAdapter(Search.this,movieList);
recyclerViewSuggestions.setAdapter(suggestionAdapter);
Log.e("TAG", "onResponse: size of movielist "+movieList);
suggestionAdapter.getFilter().filter(query);
suggestionAdapter.notifyDataSetChanged();
suggestionAdapter.setMovieList(Search.this,movieList);
}
else{
tvSuggestions.setVisibility(View.VISIBLE);
tvSuggestions.setText("No Suggestions Found");
}
/*generateDataList(movieList);
Log.d("TAG","Response = "+movieList);
slAdapter.setMovieList(getApplicationContext(),movieList);*/
}