我这里用到的是自定义HorizontalScrollView实现简单的类似Wheelview效果,不多说先看代码.
先看布局:
<vgaw.com.WheelView
android:id="@+id/wv"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<LinearLayout
android:id="@+id/ll_camera_aperture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="horizontal"></LinearLayout>
</vgaw.com.dialogfragment.WheelView>
自定义WheelView继承HorizontalScrollView.主要逻辑:
public class WheelView extends HorizontalScrollView {
private static final int CHECK_STOP_DELAY = 10;
private int itemCount = 5;
private int showItemCount = 5;
private int itemPadding = 0;
private int width;
private int itemWidth;
private WheelViewAdapter adapter;
private LinearLayout rootView;
private int currentposstion;
public WheelView(Context context, AttributeSet attrs) {
super(context, attrs);
setHorizontalScrollBarEnabled(false);
}
public void setAdapter(WheelViewAdapter adapter) {
if (adapter != null) {
this.adapter = adapter;
rootView = (LinearLayout) adapter.getRootView();
showItemCount = adapter.getShowItemCount();
if (showItemCount % 2 == 0) {
throw new RuntimeException("show item count show be odd");
}
itemCount = adapter.getItemCount();
lstI = showItemCount / 2;
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (adapter == null) {
return;
}
width = getWidth();
if (width < itemPadding) {
throw new RuntimeException("bad item padding");
}
itemWidth = (width - (showItemCount - 1) * itemPadding) / showItemCount;
for (int i = 0;i < itemCount;i++) {
final View item = adapter.getItemView(i);
item.post(new Runnable() {
@Override
public void run() {
item.setLayoutParams(new LinearLayout.LayoutParams(itemWidth, ViewGroup.LayoutParams.MATCH_PARENT));
}
});
rootView.addView(item);
}
}
private int lstScrollX;
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_UP) {
lstScrollX = getScrollX();
checkStop();
}
return super.onTouchEvent(ev);
}
private void checkStop() {
getHandler().removeCallbacks(checkStopRunnable);
postDelayed(checkStopRunnable, CHECK_STOP_DELAY);
}
private Runnable checkStopRunnable = new Runnable() {
@Override
public void run() {
int crtScrollX = getScrollX();
if (crtScrollX == lstScrollX) {
calStop();
} else {
lstScrollX = crtScrollX;
checkStop();
}
}
};
private int lstI;
private void calStop() {
if (adapter != null) {
//滑动的距离
int crtScrollX = getScrollX();
//当前滑动的多少个item
int i = crtScrollX / (itemWidth + itemPadding) - 1;
//判断当前滑动距离是否滑过半个item
int rest = crtScrollX % (itemWidth + itemPadding);
int i1 = itemWidth + itemPadding;
if (rest > (itemWidth + itemPadding) / 2) {
i++;
Log.e("rest==",rest+"//"+i1+"////"+crtScrollX);
smoothScrollBy(itemWidth + itemPadding-rest, 0);
} else {
smoothScrollBy(-rest, 0);
}
int now = i + (showItemCount / 2)+1 ;
adapter.onItemSelected(currentposstion, now, rootView.getChildAt(currentposstion), rootView.getChildAt(now));
currentposstion = now;
}
}
public void setSelectedPosstion(final int i) {
currentposstion = lstI + i;
new Handler().postDelayed((new Runnable() {
@Override
public void run() {
scrollTo(itemWidth*i,0);
adapter.onItemSelected(i+lstI, i+lstI, rootView.getChildAt(i+lstI), rootView.getChildAt(i+lstI));
}
}),270);
}
}
主要的逻辑,之前设置滚动到一个指定的位置,一直没显示后来,后来才知道 scrollTo() 是直接指定滚动条的位置, 但是由于这个动作不是单纯关于 ScrollView 而已, 还要根据 ScrollView 里面包含的View 的实际信息. 所以这动作必须在页面加载完成以后才能执行. 就设置延迟时间270.
在MainActivity这么用:
public class MainActivity extends AppCompatActivity {
private HorizontalScrollView hh;
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WheelView wv = (WheelView) findViewById(R.id.wv);
hh = (HorizontalScrollView) findViewById(R.id.hh);
final LinearLayout viewById = (LinearLayout) findViewById(R.id.ll_camera_aperture);
hh.post(new Runnable() {
@Override
public void run() {
hh.scrollTo(100,0);
}
});
wv.setAdapter(new WheelViewAdapter() {
@Override
public int getItemCount() {
return 17;
}
@Override
public int getShowItemCount() {
return 5;
}
@Override
public View getItemView(int i) {
TextView tv = new TextView(MainActivity.this);
tv.setText("hello" + i);
tv.setGravity(Gravity.CENTER);
tv.setBackgroundColor(Color.BLUE);
return tv;
}
@Override
public void onItemSelected(int lst, int now, View itemLst, View itemNow) {
itemLst.setBackgroundColor(Color.BLUE);
itemNow.setBackgroundColor(Color.RED);
}
@Override
public View getRootView() {
return viewById;
}
});
//设置选中的item
wv.setSelectedPosition(4);
wv.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
Log.e("rest",scrollX+"");
}
});
}
}
这里自定义一个Adapter
public interface WheelViewAdapter<V extends View> {
int getItemCount();
int getShowItemCount();
V getItemView(int i);
void onItemSelected(int lst, int now, View itemLst, View itemNow);
V getRootView();
}