在
ViewPager
一篇中簡單使用了原點訓示器,這裡來仿寫一個。使用自定義控件的方式來進行。然後使用
attrs.xml
聲明的方式來進行,即(主布局檔案):
<?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=".LunchIndicatorActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/indicatorViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.example.mylunch.MyIndicator
android:id="@+id/my_indicator"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="50dp"
app:Indicator_number="3"
app:Indicator_offset="0"
app:Indicator_radius="10"
app:Indicator_strokeWidth="2" />
</RelativeLayout>
首先定義自己的訓示器的
view
對象,即
MyIndicator
,如下:
public class MyIndicator extends View {
private Paint paint = new Paint();
private Paint curPaint = new Paint();
private int number = 4;
private int radius = 20;
private float offset = 2;
private int strokeWidth = 2;
public void setOffset(int position, float positionOffset){
this.offset = position + positionOffset;
// 重新繪制
invalidate();
}
private void initPaint(){
paint.setStrokeWidth(strokeWidth);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.rgb(23, 234, 120));
curPaint.setStrokeWidth(strokeWidth);
curPaint.setAntiAlias(true);
curPaint.setStyle(Paint.Style.FILL);
curPaint.setColor(Color.RED);
}
public MyIndicator(Context context) {
super(context);
}
public MyIndicator(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyIndicator);
number = array.getInt(R.styleable.MyIndicator_Indicator_number, number); // 擷取值,沒有就設定預設值4
radius = array.getInt(R.styleable.MyIndicator_Indicator_radius, radius);
strokeWidth = array.getInt(R.styleable.MyIndicator_Indicator_strokeWidth, strokeWidth);
offset = array.getFloat(R.styleable.MyIndicator_Indicator_offset, offset);
initPaint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(int i=0;i<number;i++){
canvas.drawCircle(50 + i * 3 * radius, 20, radius - strokeWidth / 2, paint);
}
canvas.drawCircle( 50 + offset * 3 * radius, 20, radius, curPaint);
}
}
在構造器中的
TypedArray
部分,也就是加載在
xml
檔案中自定義的一下屬性,即這個部分:
app:Indicator_number="3"
app:Indicator_offset="0"
app:Indicator_radius="10"
app:Indicator_strokeWidth="2"
那麼,這個自定義的和
View
相關的屬性是怎麼做關聯的呢,來自于
attrs.xml
檔案中的聲明,即:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyIndicator">
<attr name="Indicator_number" format="integer"></attr>
<attr name="Indicator_radius" format="integer"></attr>
<attr name="Indicator_offset" format="float"></attr>
<attr name="Indicator_strokeWidth" format="integer"></attr>
</declare-styleable>
</resources>
最終在
Activity
中的使用就和之前的一樣,即:
public class LunchIndicatorActivity extends AppCompatActivity {
private ViewPager viewPager;
private int[] datas = {
R.drawable.tu_1,
R.drawable.tu_2,
R.drawable.tu_3
};
private List<View> views = new ArrayList<>();
private MyIndicator indicator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lunch_indicator);
viewPager = findViewById(R.id.indicatorViewPager);
indicator = findViewById(R.id.my_indicator);
initData();
viewPager.setAdapter(new MyViewPagerAdapter());
viewPager.setOnPageChangeListener(new MyViewPagerListener());
}
class MyViewPagerListener implements ViewPager.OnPageChangeListener{
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
indicator.setOffset(position, positionOffset);
}
@Override
public void onPageSelected(int position) {}
@Override
public void onPageScrollStateChanged(int state) {}
}
private void initData(){
for(int i=0;i<datas.length;i++){
View view = getLayoutInflater().inflate(R.layout.view_pager_item, null);
ImageView imageView = view.findViewById(R.id.imageveiw);
imageView.setImageResource(datas[i]);
views.add(view);
}
}
class MyViewPagerAdapter extends PagerAdapter{
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View view = views.get(position);
container.addView(view);
return view;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView(views.get(position));
}
@Override
public int getCount() {
return datas.length;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view==object;
}
}
}
最終就可以達到一個連環的訓示器滑動的效果。