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?