如何实现Uber Eats Food Menu滚动之类的滚动功能

时间:2019-01-28 09:05:12

标签: android android-recyclerview

很抱歉,这个问题的标题不正确,我不知道如何命名

我正在开发一个小型食品订购应用程序,为此我正在实现滚动功能。

  1. 我有2个回收站视图,第一个包含食物列表,第二个包含食物类别列表
  2. 每个食物清单项目始终具有其类别名称
  3. 食物列表可垂直滚动,食物类别列表可水平滚动。

我的问题是

  1. 当我刷新食品回收站视图时,类别回收站视图项会在每次刷新时一一突出显示。 此处图片
  2. 当我滚动食物回收者视图类别时,需要自动突出显示类别项目,就像我单击类别项目时一样。

我附上了我期望的视频片段。 Here is the video

如果有人可以,请帮助我。 谢谢。

This is my Foods classFoodMenuFragment.java

public class FoodMenuFragment extends Fragment implements View.OnClickListener {

    private OnFragmentInteractionListener mListener;

    Typeface fontSemiBold;
    private static View view;
    private static RecyclerView listRecyclerView;
    private List<String> listCategoryName = new ArrayList<>();
    public static List<MenuFoods> foodListCategory = new ArrayList<>();
    private static List<MenuFoodsCategory> listArrayList = new ArrayList<>();
    public static foodsAdapter adapterFoods;

    private boolean userScrolled = true;
    int pastVisiblesItems, visibleItemCount, totalItemCount;
    private String udToken = "", restId = "";
    SessionManager session;

    TwoWayView listCategory;
    private static LinearLayoutManager mLayoutManager;
    private RecyclerView recyCategory;
    private int selectedPosition = -1;
    LinearLayoutManager layoutManager;

    private SwipeRefreshLayout swipeRefreshLayout;
    LinearLayout lineNoOffer, lineServerError;
    TextView tvServerError;
    private Dialog progressDialog;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        view = inflater.inflate(R.layout.fragment_food_menu, container, false);


        session = new SessionManager(getApplicationContext());

        swipeRefreshLayout = view.findViewById(R.id.swipe_refresh);
        lineNoOffer = view.findViewById(R.id.lineNoOffer);
        listCategory = view.findViewById(R.id.listCategory);
        //Initialize category horizontal view
        recyCategory = view.findViewById(R.id.recyCategory);
        recyCategory.setHasFixedSize(true);
        layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
        recyCategory.setLayoutManager(layoutManager);
        recyCategory.swapAdapter(new categoryAdapterNew(getApplicationContext(), listCategoryName), true);


        if (isAdded()) {
            init();
            listArrayList.clear();
            listCategoryName.clear();
            foodListCategory.clear();
            getFood();
        }
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                if (isAdded()) {
                    listArrayList.clear();
                    listCategoryName.clear();
                    foodListCategory.clear();
                    getFood();
                }
                swipeRefreshLayout.setRefreshing(false);
            }
        });

        listCategory.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //Toast.makeText(getContext(), "click"+String.valueOf(position), Toast.LENGTH_SHORT).show();
                String tmpCatego = "", tmpCategoId = "";

//             for (int i = 0; i < listCategoryName.size(); i++){
                tmpCatego = listCategoryName.get(position);
//             }
                for (int j = 0; j < listArrayList.size(); j++) {
                    if (tmpCatego.trim().toLowerCase().equals(listArrayList.get(j).getCategoryName().trim().toLowerCase())) {
                        tmpCategoId = listArrayList.get(j).getCategoryId();
                        break;
                    }
                }

                for (int i = 0; i < foodListCategory.size(); i++) {
                    if (tmpCategoId.equals(foodListCategory.get(i).getCategoryId())) {
                        listRecyclerView.smoothScrollToPosition(i);
                    }
                }
            }
        });

        recyCategory.addOnItemTouchListener(new RecyclerTouchListener(getContext(), recyCategory, new RecyclerTouchListener.ClickListener() {
            @Override
            public void onClick(View view, int position) {

                //Toast.makeText(getContext(), "click"+String.valueOf(position), Toast.LENGTH_SHORT).show();
                String tmpCatego = "", tmpCategoId = "";

//             for (int i = 0; i < listCategoryName.size(); i++){
                tmpCatego = listCategoryName.get(position);
//             }
                for (int j = 0; j < listArrayList.size(); j++) {
                    if (tmpCatego.trim().toLowerCase().equals(listArrayList.get(j).getCategoryName().trim().toLowerCase())) {
                        tmpCategoId = listArrayList.get(j).getCategoryId();
                        break;
                    }
                }

                for (int i = 0; i < foodListCategory.size(); i++) {
                    if (tmpCategoId.equals(foodListCategory.get(i).getCategoryId())) {
                        listRecyclerView.smoothScrollToPosition(i);
                    }
                }

            }

            @Override
            public void onLongClick(View view, int position) {

            }
        }));

        final int[] count = {0};
        listRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);


            }

            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

                if (isAdded()) {
                    try {

                        if (count[0] == 0) {


                            if (newState == RecyclerView.SCROLL_STATE_IDLE) {

                            }
//                      Toast.makeText(getContext(), "position "+ String.valueOf(firstVisiblePosition[0]), Toast.LENGTH_SHORT).show();
                            View visibleChild = recyclerView.getChildAt(0);
                            int positionOfChild = recyclerView.getChildAdapterPosition(visibleChild);
                            String tmpCatego = foodListCategory.get(positionOfChild).getCategoryName();

                            for (int k = 0; k < listCategoryName.size(); k++) {
                                if (tmpCatego.trim().toLowerCase().equals(listCategoryName.get(k).trim().toLowerCase())) {
                                    recyCategory.smoothScrollToPosition(k);

                                    View view = layoutManager.findViewByPosition(k);
                                    categoryAdapterNew.highlightView(view, positionOfChild);
                                }
                            }

                            count[0]++;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });


//        SnapHelper helper = new LinearSnapHelper(){
//            @Override
//            public View findSnapView(RecyclerView.LayoutManager layoutManager) {
//                View view = super.findSnapView(layoutManager);
//                try {
//                    if(view != null){
//                        final int newPos = layoutManager.getPosition(view);
//
//                        if(newPos != selectedPosition && listRecyclerView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE){
//                            selectedPosition = newPos;
//
//                            for (int j = 0; j < foodListCategory.size(); j++){
//                                if(foodListCategory.get(j).getCategoryId().trim().equals(foodListCategory.get(selectedPosition).getCategoryId())){
////                                    int categoPos = ;
//                                    for (int k = 0; k < listCategoryName.size(); k++){
//
//                                    }
//                                }
//                            }
//                        }
//                    }
//                }catch (Exception e){
//                    e.printStackTrace();
//                }
//                return view;
//            }
//        };
//        helper.attachToRecyclerView(listRecyclerView);

        return view;
    }


    private void init() {

        mLayoutManager = new LinearLayoutManager(getActivity());
        listRecyclerView = (RecyclerView) view.findViewById(R.id.linear_recyclerview);
        listRecyclerView.setHasFixedSize(true);
        listRecyclerView.setLayoutManager(mLayoutManager);// for

    }

    public void getFood() {
        progressDialog.show();

        ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
        Call<MenuFoodsResponse> call = apiInterface.getRestaurantMenuFood(restId, "foods", udToken);

        call.enqueue(new Callback<MenuFoodsResponse>() {
            @Override
            public void onResponse(@NonNull Call<MenuFoodsResponse> call, @NonNull Response<MenuFoodsResponse> response) {

                try {

                    String travelType = "";
                    if (response.body() == null) {

                    } else if (response.body().getCode() == 200) {      //If user not registered

                        listArrayList = response.body().getContent();

                        if (listArrayList.size() > 0) {

                            for (int j = 0; j < listArrayList.size(); j++) {
                                foodListCategory.addAll(listArrayList.get(j).getContent());
                                for (int k = 0; k < foodListCategory.size(); k++) {

                                    if (!listCategoryName.contains(listArrayList.get(j).getCategoryName())) {
                                        listCategoryName.add(listArrayList.get(j).getCategoryName());
                                    }

                                    if (foodListCategory.get(k).getCategoryId() == null) {
                                        foodListCategory.get(k).setCategoryId(listArrayList.get(j).getCategoryId());
                                        foodListCategory.get(k).setCategoryName(listArrayList.get(j).getCategoryName());
                                    }
                                }
                            }
                            adapterFoods = new foodsAdapter(getActivity(), foodListCategory);
                            listRecyclerView.setAdapter(adapterFoods);
                            adapterFoods.notifyDataSetChanged();

                            //Show Category list
//                            categoryAdapter myAdapter1 = new categoryAdapter(getContext(), R.layout.custom_category_list_item, listCategoryName);
//                            listCategory.setAdapter(myAdapter1);

                            recyCategory.swapAdapter(new categoryAdapterNew(getApplicationContext(), listCategoryName), true);

                            lineNoOffer.setVisibility(View.GONE);
                        } else {
                            lineNoOffer.setVisibility(View.VISIBLE);
                        }

                    } else {        //If user already registered

                        String errorMessage = response.body().getMessage();
                        String errorCode = response.body().getErrorCode();
                        Toast.makeText(getActivity(), errorMessage + "(" + errorCode + ")", Toast.LENGTH_SHORT).show();

                    }

                    progressDialog.dismiss();
                } catch (Exception e) {
                    e.printStackTrace();
                    progressDialog.dismiss();
                }
            }

            @Override
            public void onFailure(@NonNull Call<MenuFoodsResponse> call, @NonNull Throwable t) {
                Log.e("TAG", t.toString());
                t.printStackTrace();
                Toast.makeText(getApplicationContext(), "Error :" + t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
                progressDialog.dismiss();
            }
        });

    }

    @Override
    public void onClick(View v) {

    }
}

This is Food layoutfragment_food_menu.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.urbandine.home.FoodMenuFragment">

    <!-- TODO: Update blank fragment layout -->

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/recyCategory"
                android:background="@color/white_color"
                android:layout_alignParentTop="true"/>

            <android.support.v7.widget.RecyclerView
                android:layout_below="@+id/recyCategory"
                android:id="@+id/linear_recyclerview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/light_grey_color" />

        </RelativeLayout>

</LinearLayout>

This is foods adapter classfoodsAdapter.java

public class foodsAdapter extends RecyclerView.Adapter<FoodsViewHolder>  {

    private List<MenuFoods> arrayList;
    private List<MenuFoods> arrayListFiltered;
    private Context context;
    private LinearLayout lineSmall, lineMedium, lineLarge;
    private TextView tvPriceSmall, tvPriceMedium, tvPriceLarge, tvDishCount1, tvDishCount2, tvDishCount3;
    private ImageView ivAddSmall, ivAddMedium, ivAddLarge, ivRemoveSmall, ivRemoveMedium, ivRemoveLarge;


    public foodsAdapter(Context context, List<MenuFoods> arrayList) {
        this.context = context;
        this.arrayList = arrayList;
        this.arrayListFiltered = arrayList;
    }

    @Override
    public int getItemCount() {
        return (null != arrayListFiltered ? arrayListFiltered.size() : 0);
    }

    @Override
    public void onBindViewHolder(FoodsViewHolder holder, final int position) {

        if (arrayListFiltered.size() > 0) {

            final MenuFoods model = arrayListFiltered.get(position);

                    FoodsViewHolder mainHolder = (FoodsViewHolder) holder;// holder

               }
            }

            // Implement click listener over layout
            mainHolder.setOnClickListener(new OnRecyclerItemClickListener() {
                @Override
                public void onItemClickListener(View v, int pos) {
                    switch (v.getId()) {
                        case R.id.mainDrinks:

                            Activity activity = (Activity) context;

                            Intent intent = new Intent(context, DishDetailActivity.class);
                            context.startActivity(intent);
                            activity.overridePendingTransition(R.anim.push_right_out, R.anim.push_right_in);

                            break;
                    }
                }
            });

        }
    }

    @Override
    public FoodsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

        // This method will inflate the custom layout and return as viewholder
        LayoutInflater mInflater = LayoutInflater.from(viewGroup.getContext());

        ViewGroup mainGroup = (ViewGroup) mInflater.inflate(R.layout.custom_foods_item, viewGroup, false);
        FoodsViewHolder listHolder = new FoodsViewHolder(mainGroup);
        return listHolder;

    }

}

My category view adaptercategoryAdapterNew.java

public class categoryAdapterNew extends RecyclerView.Adapter<categoryAdapterNew.CategoViewHolder> {

    private List<String> amiItem = new ArrayList<>();
    Context context;
    private static Context context1;
    private static TextView lastChecked = null;

    public class CategoViewHolder extends RecyclerView.ViewHolder {

     TextView textView;

        public CategoViewHolder(View view) {
            super(view);
            textView = view.findViewById(R.id.tvCuisine);
        }
    }

    public categoryAdapterNew(Context context, List<String> categoList) {
        this.context = context;
        this.amiItem = categoList;
        this.context1 = context;
    }

    @NonNull
    @Override
    public categoryAdapterNew.CategoViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.custom_category_list_item, viewGroup, false);

        return new categoryAdapterNew.CategoViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull categoryAdapterNew.CategoViewHolder holder, int i) {
        if(amiItem.size() > 0){

            holder.textView.setText(amiItem.get(i));

            //for default highlight first item on category recycler view
            if(i == 0 && !holder.textView.isSelected()){

                lastChecked = holder.textView;
                lastCheckedPos  = 0;
                lastChecked.setTextColor(context1.getResources().getColor(R.color.red_color));
                lastChecked.setSelected(true);
            }

            //Highlight textView when click on category item
            holder.textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    TextView tv = (TextView)v;
                    int clickPos = -1;

                    for(int k = 0; k < amiItem.size(); k++){
                        if(tv.getText().toString().trim().toLowerCase().equals(amiItem.get(k).trim().toLowerCase())){
                            clickPos = k;
                            break;
                        }
                    }

                    if(!tv.isSelected()){
                        if(lastChecked != null){
                            lastChecked.setSelected(false);
                            lastChecked.setTextColor(context1.getResources().getColor(R.color.text_color));
                        }
                        lastChecked = tv;
                        tv.setSelected(true);
                        tv.setTextColor(context1.getResources().getColor(R.color.red_color));
                        lastCheckedPos = clickPos;
                    }
                }
            });
        }
    }

    //Highlight category item when scroll dish recycler view
    public static void highlightView(View view, int pos){
        TextView textView = (TextView)view.findViewById(R.id.tvCuisine);

        if(!textView.isSelected()){
            if(lastChecked != null){
                lastChecked.setSelected(false);
                lastChecked.setTextColor(context1.getResources().getColor(R.color.text_color));
            }
            lastChecked = textView;
            textView.setSelected(true);
            textView.setTextColor(context1.getResources().getColor(R.color.red_color));
            lastCheckedPos = pos;
        }
    }

    @Override
    public int getItemCount() {
        return amiItem.size();
    }
}

1 个答案:

答案 0 :(得分:1)

很简单,当需要选择用户滚动到特定点的选项卡并且显示选项卡布局时,您必须在项目的水平滚动视图和垂直滚动视图中采用两种不同的布局选项卡布局。