代码之家  ›  专栏  ›  技术社区  ›  Waseem

如何实现Uber吃东西菜单滚动等滚动功能

  •  -2
  • Waseem  · 技术社区  · 7 年前

    抱歉,问题标题不好,我不知道如何命名此功能

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

    我的问题是,

    1. 当我刷新食品回收器视图时,类别回收器会为每次刷新逐个查看突出显示的项目。 这是图像
    2. 当我滚动食品回收查看类别项目自动需要突出显示,就像我如何点击类别项目。

    我附上了一个视频剪辑正是我所期待的。 Here is the video

    非常感谢。

    This is my Foods class FoodMenuFragment.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 layout ( fragment_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 class foodsAdapter.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 adapter ( categoryAdapterNew.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 回复  |  直到 7 年前
        1
  •  1
  •   Vrushi Patel    7 年前

    它很简单,你必须采取两种不同的布局选项卡布局水平滚动和垂直滚动查看项目时,用户滚动到特定的点选项卡需要选择和选项卡布局可见。