Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

control fling speed for recycler view

I have a RecyclerView in which i have an image ,a few TextViews and 2 ImageButtons. I have 7-8 such rows to display in my Activity. The scroll is very smooth in android 4.4.4 and below versions but it kind of gives some jerking effect in lollipop. I think that controlling the fling speed for the RecyclerView will do the trick. I searched for it, but found nothing.Instead i found how to take the view to a particular position for the fling.

But I want to control the fling speed. Can friction be used. And how to use friction.

menuRecyclerView = (RecyclerView) findViewById(R.id.menuList);
menuRecyclerView.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(context);
menuRecyclerView.setLayoutManager(llm);     
Scroller sc = new Scroller(context);
sc.setFriction(ViewConfiguration.getScrollFriction() * 10);

This is my adapter to set rcycler view layout.

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.bumptech.glide.Glide;

import news.circle.circle.R;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.CustomViewHolder> {
    public RecyclerViewAdapter(Context context, List<MenuDescription> listOrder, DatabaseHandlerCart db
            , List<MenuDescription> vegList, List<MenuDescription> nonVegList, String menuTextData) {
        this.listOrder = listOrder;
        this.inflater = LayoutInflater.from(context);
        this.context = context;
        imageLoader = new ImageLoader(context);
        this.db = db;
        this.vegList = vegList;
        this.nonVegList = nonVegList;
        this.completeList = listOrder;
        this.menuTextData = menuTextData;
    }

    @Override
    public RecyclerViewAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_ITEM) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view, parent, false);
            return new CustomViewHolder(view, viewType);
        } else if (viewType == TYPE_HEADER) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header, parent, false);
            return new CustomViewHolder(view, viewType);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(final RecyclerViewAdapter.CustomViewHolder holder, int position) {
        if (holder.Holderid == 1) {
            final MenuDescription menu = listOrder.get(position - 1);
            holder.title.setText(menu.getName() + "");
            holder.quant.setText(menu.getQuantity() + "");
            holder.description.setText(menu.getDescription());
            holder.title.setTypeface(Fonts.getFont(context, Constants.AVENIR_REGULAR));
            holder.description.setTypeface(Fonts.getFont(context, Constants.AVENIR_REGULAR));
            Glide.with(context).load(menu.getFlag_path()).placeholder(R.drawable.ic_order_now).fitCenter().into(holder.image);
            holder.inc.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    if (Constants.internet) {
                        menu.decrQuantity();
                        if (menu.getQuantity() == 0) {
                            menu.setDecr_button_visibility(0);
                            try {
                                db.DeleteCartItem(menu.getItem_id());
                            } catch (SQLException e) {
                                e.printStackTrace();
                            }
                        } else {
                            try {
                                db.updateQuantity(menu.getQuantity(), menu.getItem_id());
                            } catch (SQLException e) {
                                e.printStackTrace();
                            }
                        }
                        holder.quant.setText(menu.getQuantity() + "");
                        notifyDataSetChanged();
                    } else {
                        Toast.makeText(context, "Please check your internet connection", Toast.LENGTH_SHORT).
                    }
                    show();
                }
            });
            holder.decr.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (Constants.internet) {
                        try {
                            if (!db.CheckIsItemAlreadyInDBorNot(menu.getItem_id(), "cart")) {
                                menu.incrQuantity();
                                db.addDataToCart(menu);
                                // cart_items.add(menu);

                                holder.quant.setText(menu.getQuantity() + "");
                            } else {
                                menu.incrQuantity();
                                db.updateQuantity(menu.getQuantity(), menu.getItem_id());
                                holder.quant.setText(menu.getQuantity() + "");
                            }

                        } catch (SQLException | IllegalStateException e) {
                            e.printStackTrace();
                        }


                        if (menu.getDecr_button_visibility() == 1) {
                            holder.decr.setVisibility(View.VISIBLE);
                            holder.quant.setVisibility(View.VISIBLE);
                            if (total == 1)
                                RecyclerViewMainActivity.bottomBarUp();

                            notifyDataSetChanged();
                        } else
                            Toast.makeText(context, "Please check your internet connection", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }

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

    @Override
    public int getItemViewType(int position) {
        if (isPositionHeader(position))
            return TYPE_HEADER;
        return TYPE_ITEM;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    private boolean isPositionHeader(int position) {
        return position == 0;
    }
}
like image 619
Abhishek Lodha Avatar asked Aug 20 '15 14:08

Abhishek Lodha


People also ask

How can I control the scrolling speed of RecyclerView?

getHeight(); recyclerView. smoothScrollToPosition(height); recyclerView. postDelayed(new Runnable() { public void run() { recyclerView. smoothScrollToPosition(0); } },200);

What is smooth scrolling in RecyclerView Android?

RecyclerView.SmoothScroller implementation which uses a LinearInterpolator until the target position becomes a child of the RecyclerView and then uses a DecelerateInterpolator to slowly approach to target position. Base class for smooth scrolling.

When should I use a recycler view?

Use the RecyclerView widget when you have data collections whose elements change at runtime based on user action or network events. If you want to use a RecyclerView , you will need to work with the following: RecyclerView. Adapter - To handle the data collection and bind it to the view.


2 Answers

There is one RecyclerView method specifically designed to control the fling speed you only need to override it to achieve the friction/slowdown effect you mentioned in your question.

One simple implementation you could try:

@Override
public boolean fling(int velocityX, int velocityY)
{

     // if FLING_SPEED_FACTOR between [0, 1[ => slowdown 
     velocityY *= FLING_SPEED_FACTOR; 

     return super.fling(velocityX, velocityY);
} 
like image 143
HenriqueMS Avatar answered Sep 29 '22 05:09

HenriqueMS


This works nicely to put a maximum threshold on the fling speed:

mRecyclerView.setOnFlingListener(new RecyclerView.OnFlingListener() {

    @Override
    public boolean onFling(int velocityX, int velocityY) {

        if (Math.abs(velocityY) > MAX_VELOCITY_Y) {
            velocityY = MAX_VELOCITY_Y * (int) Math.signum((double)velocityY);
            mRecyclerView.fling(velocityX, velocityY);
            return true;
        }

        return false;
    }
});
like image 40
MikeMcC Avatar answered Sep 29 '22 05:09

MikeMcC