I´m working on a project where I´m trying to implement a settings filter which alows a user to get individual results. The user should be able to choose different options to get individual results displayed in a paged recyclerview.
My first try
First I tried to achive that with different relativ layouts which included checkboxes and next to the checkboxes a textview which displays the size of the results for that single option. Cause my view gots to big I switched to a recyclerview as a list which should display some constant options for different categorys but with changing counters.
So I set up a recyclerview, a model class for the recyclerview adapter and an adapter. The order of the items should always be the same and also the text shouldn´t change at any time only the result size for the single options should change. Everything works beside of that fact that the order switch any time when I start a new session I got the result size for any option with a viewmodel and a web request.
My model class:
public class FilterItem implements Serializable {
public boolean state;
public String ItemName;
public Integer ItemCount;
public FilterItem (){}
public FilterItem(Boolean state,String ItemName,Integer ItemCount)
{
this.state=state;
this.ItemName=ItemName;
this.ItemCount=ItemCount;
}
}
My Adapter:+ public class FilterListRecycler extends RecyclerView.Adapter<FilterListRecycler.FilterItemHolder> {
ArrayList<FilterItem> filterItem;
private final FilterItemInterface filterItemInterface;
Boolean isSelectedAll=true;
public FilterListRecycler(ArrayList<FilterItem> filterItem , FilterItemInterface filterItemInterface)
{
this.filterItem=filterItem;
this.filterItemInterface=filterItemInterface;
}
public void unselectall(){
isSelectedAll=false;
notifyDataSetChanged();
}
@Override
public @NotNull FilterItemHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
return new FilterItemHolder(FilterlistitemBinding.inflate(LayoutInflater.from(viewGroup.getContext())));
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull FilterItemHolder holder, int position) {
Log.d("TAG", "onBindViewHolder: "+position+" "+filterItem.get(position).state+" "+filterItem.get(position).ItemName+" "+filterItem.get(position).ItemCount);
holder.filterlistitemBinding.checkbox.setChecked(filterItem.get(position).state);
holder.filterlistitemBinding.checkbox.setText(filterItem.get(position).ItemName);
holder.filterlistitemBinding.counter.setText("("+filterItem.get(position).ItemCount+")");
if (!isSelectedAll) {
holder.filterlistitemBinding.checkbox.setChecked(false);
filterItem.get(position).state=false;
}
holder.filterlistitemBinding.checkbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
filterItemInterface.getFilterItem(filterItem.get(position));
}
});
}
@Override
public int getItemCount() {
return filterItem.size();
}
public static class FilterItemHolder extends RecyclerView.ViewHolder {
public FilterlistitemBinding filterlistitemBinding;
public FilterItemHolder(FilterlistitemBinding filterlistitemBinding) {
super(filterlistitemBinding.getRoot());
this.filterlistitemBinding = filterlistitemBinding;
}
}
}
Short version of my settings filter class:
public class Config_Filter extends DialogFragment implements FilterItemInterface {
FilterItem filterItem;
ArrayList<FilterItem> filterItems;
Bundle filterbundle;
FilterStates filterStates;
String adress;
MainViewModel viewModel;
LocationViewModel locationViewModel;
private final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
ArrayList<String> Genre,Art,Extra;
int radius=25, age, privat,StartPrice,EndPrice;
String starttime,endtime;
FilterListRecycler filterListRecycler;
double lat,lng;
public String Date;
public static final String TAG = "config_dialog";
FragmentConfigBinding binding;
@Override
public void onStart() {
super.onStart();
//dialog settings
Dialog dialog = getDialog();
if (dialog != null) {
int width = ViewGroup.MarginLayoutParams.MATCH_PARENT;
int height = ViewGroup.LayoutParams.MATCH_PARENT;
dialog.getWindow().setLayout(width, height);
ColorDrawable back = new ColorDrawable(Color.TRANSPARENT);
InsetDrawable inset = new InsetDrawable(back, 0, 60, 0, 0);
dialog.getWindow().setBackgroundDrawable(inset);
dialog.getWindow().setWindowAnimations(R.style.AppTheme_Slide);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
setStyle(DialogFragment.STYLE_NO_FRAME, R.style.AppTheme_FullScreenDialog);
super.onCreate(savedInstanceState);
//current adress of user and lat and lng to get location oriented results
lat=requireArguments().getDouble(Config.KEY_EMP_LAT);
lng=requireArguments().getDouble(Config.KEY_EMP_LNG);
}
@SuppressLint({"SetTextI18n", "DefaultLocale"})
@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding = FragmentConfigBinding.inflate(inflater, container, false);
//setup ArrayLists
Genre=new ArrayList<>();
Art=new ArrayList<>();
Extra=new ArrayList<>();
filterItems=new ArrayList<>();
expandLayout();
ViewModel();
filtercount();
recycler();
RecyclerAdapter();
return binding.getRoot();
}
public void filterartitems()
{
filterItems.add(new FilterItem(false,getString(R.string.Bar),0));
filterItems.add(new FilterItem(false,getString(R.string.Club),0));
filterItems.add(new FilterItem(false,getString(R.string.Festival),0));
filterItems.add(new FilterItem(false,getString(R.string.OpenAir),0));
}
public void ViewModel()
{
viewModel = new ViewModelProvider(requireActivity()).get(MainViewModel.class);
locationViewModel=new ViewModelProvider(requireActivity()).get(LocationViewModel.class);
}
public void recycler()
{
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
binding.expandart.setLayoutManager(new LinearLayoutManager(getContext()));
}
public boolean cleanParams()
{
return Art.size() == 0 || Genre.size() == 0 || privat == 0 || age == 0 || radius == 25 || starttime.equals(getString(R.string.start)) || endtime.equals(getString(R.string.end)) || Date.equals(getString(R.string.Datum));
}
//count result size for the single options
@SuppressLint("SetTextI18n")
public void filtercount()
{
viewModel.getFilteredData(lat,lng,firebaseAuth.getUid(),new ArrayList<String>(Collections.singletonList(getString(R.string.Bar))),Genre,Extra,privat,age,radius,starttime,endtime,StartPrice,EndPrice,Date).observe(getViewLifecycleOwner(), integer ->{
if (filterItems.size() == 1) {
filterItems.set(0, new FilterItem(filterItems.get(0).state, filterItems.get(0).ItemName, integer));
filterListRecycler.notifyItemChanged(0);
}
filterItems.add(new FilterItem(false,getString(R.string.Bar),integer));
});
viewModel.getFilteredData(lat,lng,firebaseAuth.getUid(), new ArrayList<>(Collections.singletonList(getString(R.string.Club))),Genre,Extra,privat,age,radius,starttime,endtime,StartPrice,EndPrice,Date).observe(getViewLifecycleOwner(), integer ->{
if (filterItems.size()==2) {
filterItems.set(1, new FilterItem(filterItems.get(1).state, filterItems.get(1).ItemName, integer));
filterListRecycler.notifyItemChanged(1);
}
filterItems.add(new FilterItem(false,getString(R.string.Club),integer));
});
viewModel.getFilteredData(lat,lng,firebaseAuth.getUid(), new ArrayList<>(Collections.singletonList(getString(R.string.Festival))),Genre,Extra,privat,age,radius,starttime,endtime,StartPrice,EndPrice,Date).observe(getViewLifecycleOwner(), integer -> {
if (filterItems.size()==3) {
filterItems.set(2, new FilterItem(filterItems.get(2).state, filterItems.get(2).ItemName, integer));
filterListRecycler.notifyItemChanged(2);
}
filterItems.add(new FilterItem(false,getString(R.string.Festival),integer));
});
viewModel.getFilteredData(lat,lng,firebaseAuth.getUid(), new ArrayList<>(Collections.singletonList(getString(R.string.OpenAir))),Genre,Extra,privat,age,radius,starttime,endtime,StartPrice,EndPrice,Date).observe(getViewLifecycleOwner(), integer ->{
if (filterItems.size()==4) {
filterItems.set(3, new FilterItem(filterItems.get(3).state, filterItems.get(3).ItemName, integer));
filterListRecycler.notifyItemChanged(3);
}
filterItems.add(new FilterItem(false,getString(R.string.OpenAir),integer));
});
}
public void RecyclerAdapter()
{
filterListRecycler=new FilterListRecycler(filterItems,this);
binding.expandart.setAdapter(filterListRecycler);
}
public void expandLayout()
{
binding.ArtConfig.setOnClickListener(v -> {
if (binding.expandart.getVisibility()==View.GONE) {
expand(binding.expandart);
binding.ArtConfig.setActivated(true);
}
else {
collapse(binding.expandart);
binding.ArtConfig.setActivated(false);
}
});
}
@Override
public void getFilterItem(FilterItem filterItem) {
}
public static void expand(final View v) {
int matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) v.getParent()).getWidth(), View.MeasureSpec.EXACTLY);
int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
v.measure(matchParentMeasureSpec, wrapContentMeasureSpec);
final int targetHeight = v.getMeasuredHeight();
// Older versions of android (pre API 21) cancel animations for views with a height of 0.
v.getLayoutParams().height = 1;
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? LinearLayout.LayoutParams.WRAP_CONTENT
: (int)(targetHeight * interpolatedTime);
v.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
// Expansion speed of 1dp/ms
a.setDuration((int)(targetHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
public static void collapse(final View v) {
final int initialHeight = v.getMeasuredHeight();
Animation a = new Animation()
{
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if(interpolatedTime == 1){
v.setVisibility(View.GONE);
}else{
v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);
v.requestLayout();
}
}
@Override
public boolean willChangeBounds() {
return true;
}
};
// Collapse speed of 1dp/ms
a.setDuration((int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
Aucun commentaire:
Enregistrer un commentaire