項目中多多少少都會用到一個view,類似於indicatior,viewpager滑動到第幾個,第幾個點選中,本身這個東西實現由很多方式,並不難,可以在xml 寫,但是代碼量有點大,還是做成一個view拿來用就行,今天就帶來這個簡單的view
如下圖:
我們只要像textview一樣使用就能達到下面幾個點點的效果,
首先我們分析下我們支持的擴展屬性
"> <attr name="point_view_selector_background" format="reference" />
<attr name="point_view_point_size" format="dimension" />
<attr name="point_view_point_margin" format="dimension" />
</declare-styleable>
這裏我提供了三個屬性,一個是點點的選擇狀態,另外是點點的大小,和點點的間距,
ok,自定義屬性,完畢,我們開始寫我們的view
這個view其實繼承viewgroup 比繼承view好實現,所以我繼承了Lxxxayout,
這樣我們可以不用管方向 只要管好裏面子view的間距即可
如下;
我們在構造函數中獲取自定義屬性
public ATDotPointView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOrientation(HORIZONTAL);
setGravity(Gravity.CENTER);
dotList = new ArrayList<>();
DisplayMetrics metrics = getResources().getDisplayMetrics();
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ATDotPointView, defStyleAttr, 0);
int indexCount = typedArray.getIndexCount();
for (int i = 0; i < indexCount; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.ATDotPointView_point_view_selector_background:
mDotPintBackgroundRes = typedArray.getResourceId(attr, 0);
break;
case R.styleable.ATDotPointView_point_view_point_size:
pointSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, POINT_DE_SIZE, metrics));
break;
case R.styleable.ATDotPointView_point_view_point_margin:
pointMargin = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, POINT_DE_MARGIN, metrics));
break;
}
}
typedArray.recycle();
pointSize = pointSize == 0 ? (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, POINT_DE_SIZE, metrics) : pointSize;
pointMargin = pointMargin == 0 ? (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, POINT_DE_MARGIN, metrics) : pointMargin;
}
獲取屬性完畢後,我們提供生成一個小球的方法
/**
* generate dot point
*/
private View generateDotPoint() {
View view = new View(getContext());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(pointSize, pointSize);
params.rightMargin = pointMargin;
view.setLayoutParams(params);
view.setBackgroundResource(mDotPintBackgroundRes);
return view;
}
直接返回一個view即可,
提供添加小球的方法
/**
* add point into point view
*
* @param dotPointCount point count;
*/
public void addPoint2View(int dotPointCount) {
removeAllViews();
dotList.clear();
for (int i = 0; i < dotPointCount; i++) {
View dotPoint = generateDotPoint();
dotList.add(dotPoint);
addView(dotPoint);
}
// default first point select
setDotPointSelecedByInDex(0);
}
提供選中當前小球的方法
/**
* set point select
*
* @param index select index
*/
public void setDotPointSelecedByInDex(int index) {
resetPointViewState();
dotList.get(index).setSelected(true);
}
ok 到此我們的view定義完畢,這樣 無論哪個界面用到指點的時候,只需要引入你的view即可,很簡單下面把完整的view代碼放下面.
public class ATDotPointView extends LinearLayout {
private static final int POINT_DE_SIZE = 9;
private static final float POINT_DE_MARGIN = 12;
private List<View> dotList;
private int mDotPintBackgroundRes;
private int pointSize;
private int pointMargin;
public ATDotPointView(Context context) {
this(context, null);
}
public ATDotPointView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ATDotPointView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOrientation(HORIZONTAL);
setGravity(Gravity.CENTER);
dotList = new ArrayList<>();
DisplayMetrics metrics = getResources().getDisplayMetrics();
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ATDotPointView, defStyleAttr, 0);
int indexCount = typedArray.getIndexCount();
for (int i = 0; i < indexCount; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.ATDotPointView_point_view_selector_background:
mDotPintBackgroundRes = typedArray.getResourceId(attr, 0);
break;
case R.styleable.ATDotPointView_point_view_point_size:
pointSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, POINT_DE_SIZE, metrics));
break;
case R.styleable.ATDotPointView_point_view_point_margin:
pointMargin = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, POINT_DE_MARGIN, metrics));
break;
}
}
typedArray.recycle();
pointSize = pointSize == 0 ? (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, POINT_DE_SIZE, metrics) : pointSize;
pointMargin = pointMargin == 0 ? (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, POINT_DE_MARGIN, metrics) : pointMargin;
}
/**
* add point into point view
*
* @param dotPointCount point count;
*/
public void addPoint2View(int dotPointCount) {
removeAllViews();
dotList.clear();
for (int i = 0; i < dotPointCount; i++) {
View dotPoint = generateDotPoint();
dotList.add(dotPoint);
addView(dotPoint);
}
// default first point select
setDotPointSelecedByInDex(0);
}
/**
* generate dot point
*/
private View generateDotPoint() {
View view = new View(getContext());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(pointSize, pointSize);
params.rightMargin = pointMargin;
view.setLayoutParams(params);
view.setBackgroundResource(mDotPintBackgroundRes);
return view;
}
/**
* set all point selected false
*/
private void resetPointViewState() {
for (View pointView : dotList) {
pointView.setSelected(false);
}
}
/**
* set point select
*
* @param index select index
*/
public void setDotPointSelecedByInDex(int index) {
resetPointViewState();
dotList.get(index).setSelected(true);
}
}