如图所示, 完全自定义的ScrollBar, 并且实现了拖动功能
布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.test.demoone.scrollbar.ScrollBarActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/toastView"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:gravity="center"
android:textColor="@color/colorAccent"
android:textSize="50sp" />
<View
android:id="@+id/scrollBar"
android:layout_width="50dp"
android:layout_height="100dp"
android:layout_alignParentRight="true"
android:background="@color/colorAccent" />
</RelativeLayout>
逻辑代码:
public class ScrollBarActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private Context context;
private View bar;
private float barTouchedLastY;
private TextView toastView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scroll_bar);
context = this;
recyclerView = findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(new MyAdapter());
bar = findViewById(R.id.scrollBar);
toastView = findViewById(R.id.toastView);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
changeBarPosition();
}
});
bar.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
barTouchedLastY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
float dY = event.getRawY() - barTouchedLastY;
moveListView(dY);
showToastView();
barTouchedLastY = event.getRawY();
//上下边界值
if (bar.getY() + dY + bar.getMeasuredHeight() >= recyclerView.getHeight()) {
//到底了
bar.setY(recyclerView.getHeight() - bar.getMeasuredHeight());
} else if (bar.getY() + dY <= 0) {
//到顶了
bar.setY(0);
} else {
bar.setY(bar.getY() + dY);
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
break;
}
return true;
}
});
}
private void showToastView() {
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
int position = layoutManager.findFirstVisibleItemPosition();
toastView.setText("" + position);
}
private void moveListView(float dY) {
//列表总长度
int verticalScrollRange = recyclerView.computeVerticalScrollRange();
//可见区域长度
int verticalScrollExtent = recyclerView.computeVerticalScrollExtent();
//向上滑动的大概距离
int verticalScrollOffset = recyclerView.computeVerticalScrollOffset();
int listMovableHeight = verticalScrollRange - verticalScrollExtent;
int barMovableHeight = verticalScrollExtent - bar.getHeight();
recyclerView.scrollBy(0, (int) (1.0f * listMovableHeight / barMovableHeight * dY));
}
private void changeBarPosition() {
//列表总长度
int verticalScrollRange = recyclerView.computeVerticalScrollRange();
//可见区域长度
int verticalScrollExtent = recyclerView.computeVerticalScrollExtent();
//向上滑动的大概距离
int verticalScrollOffset = recyclerView.computeVerticalScrollOffset();
int listMovableHeight = verticalScrollRange - verticalScrollExtent;
int barMovableHeight = verticalScrollExtent - bar.getHeight();
bar.setY(1.0f * barMovableHeight / listMovableHeight * verticalScrollOffset);
}
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(R.layout.item_view, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
holder = (MyViewHolder) holder;
((MyViewHolder) holder).textView.setText("Hello Position " + position);
}
@Override
public int getItemCount() {
return 100;
}
class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
}
}
}
}
关键代码就只有两个方法: moveListView 和 changeBarPosition,
为了粘贴方便, 随便写的Adapter也粘出来了, 还请不要吐槽...