I am programming an app that can execute many commands with one click. In the setting, for the command selection I use a AutoCompleteTextView with a TabLayout menu.
Here is the code:
AutoCompleteTextView type = holder.type;
type.setText(command.getType().getName(), false);
String[] commandList = CommandType.getNames();
ArrayList<String> list = new ArrayList<>();
list.add("Test");
SelectionAdapter selectionAdapter =
new SelectionAdapter(type, this.context, list);
// ArrayAdapter arrayAdapter = new ArrayAdapter(this.context,
// R.layout.type_selection_item, commandList);
type.setAdapter(selectionAdapter);
SelectionAdapter Class:
public class SelectionAdapter extends ArrayAdapter {
private Context context;
private RecyclerView items;
private CommandCategory category;
private AutoCompleteTextView autoCompleteTextView;
public SelectionAdapter(AutoCompleteTextView autoCompleteTextView,
@NonNull Context context, ArrayList<String> test) {
super(context, 0, test);
this.context = context;
this.autoCompleteTextView = autoCompleteTextView;
}
@Override
public View getView(int position, @Nullable View covertView, @NonNull ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.command_selection, parent,
false);
TabLayout tabLayout = rowView.findViewById(R.id.commandselection_categories);
CommandCategory[] categories = CommandCategory.values();
this.category = CommandCategory.GENEREAL;
for (CommandCategory category : categories) {
TabLayout.Tab tab = tabLayout.newTab();
tab.setText(category.getName());
tabLayout.addTab(tab);
}
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
category = CommandCategory.getTypeByName(tab.getText().toString());
onCategoryChange();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
this.items = rowView.findViewById(R.id.commandselection_items);
GridLayoutManager manager = new GridLayoutManager(getContext(),
2, GridLayoutManager.VERTICAL, false);
this.items.setLayoutManager(manager);
CommandType[] types = CommandType.values();
ArrayList<CommandType> typesOfCategory = new ArrayList<>();
for (CommandType type : types)
if (CommandType.getCategory(type) == this.category)
typesOfCategory.add(type);
SelectionItemsAdapter adapter = new SelectionItemsAdapter(this.autoCompleteTextView,
this.context, typesOfCategory);
this.items.setAdapter(adapter);
return rowView;
}
@Override
public int getCount() {
return 1;
}
private void onCategoryChange() {
CommandType[] types = CommandType.values();
ArrayList<CommandType> typesOfCategory = new ArrayList<>();
for (CommandType type : types)
if (CommandType.getCategory(type) == this.category)
typesOfCategory.add(type);
SelectionItemsAdapter selectionItemsAdapter = (SelectionItemsAdapter) this.items.getAdapter();
selectionItemsAdapter.updateItems(typesOfCategory);
selectionItemsAdapter.notifyDataSetChanged();
} }
The SelectionItemsAdapter Class:
public class SelectionItemsAdapter extends RecyclerView.Adapter<SelectionItemsAdapter.ViewHolder> {
private ArrayList<CommandType> types;
private LayoutInflater inflater;
private AutoCompleteTextView autoCompleteTextView;
public SelectionItemsAdapter(AutoCompleteTextView autoCompleteTextView, Context context, ArrayList<CommandType> commandTypes) {
this.types = commandTypes;
this.inflater = LayoutInflater.from(context);
this.autoCompleteTextView = autoCompleteTextView;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.type_selection_item, parent, false);
return new SelectionItemsAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
CommandType type = types.get(position);
TextView textView = holder.nameView;
textView.setText(type.getName());
}
public void updateItems(ArrayList<CommandType> types) {
this.types = types;
System.out.println("ItemCount: " types.size());
}
@Override
public int getItemCount() {
return types.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements GestureDetector.OnGestureListener {
GestureDetector gestureDetector;
ConstraintLayout constraintLayout;
TextView nameView;
public ViewHolder(@NonNull View view) {
super(view);
this.constraintLayout = view.findViewById(R.id.type_layout);
this.gestureDetector = new GestureDetector(view.getContext(), this);
this.nameView = view.findViewById(R.id.type_item);
this.nameView.setOnClickListener( event -> {
CommandType type = types.get(getAdapterPosition());
autoCompleteTextView.setText(type.getName());
});
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
}}
The problem I have is that when I update the RecyclerView the changes don't become visible. items doesn't change
With debugging I could see that the problem is in the SelectionAdapter class in the onCategoryChange() method.
Actually I also found the "solution" to this problem, if I add this.notifyDataSetChanged();
to the onCategoryChange() method and also change some code in the getView method, then I can navigate with the tablayout.
But then I have another problem, then the Tablayout doesn't work as it should.
Like the click animation will be cancelled and if you would click on a tab that isn't fully visible, then normally it would be set completely visible, but that doesn't work too.
How can I fix both my problems?
CodePudding user response:
I didn't check the issue properly, but you could check using notifyItemChanged(...) and related methods instead of notifyDataSetChanged() because you don't want to reload all items in the RecyclerView. Maybe it would help.
CodePudding user response:
I couldn't find a solution to this problem with an ArrayAdapter and an AutoCompleteTextView. But it was possible with a Spinner. So I created a custom spinner adapter that implements SpinnerAdapter and now it works! This is not an easy solution but unfortunately I couldn't find a easy one at all.