viewgroup 中是存放 view 和 viewgroup 的,下面是小例子,仅用来学习 viewgroup 的基本函数作用
1.自定义 继承 viewgroup 的类
public class MyViewG extends ViewGroup {
private String TAG = "MyViewG";
private GestureDetector detector = null;
private int lastX = 0;
private Scroller mscroller = null;
private int viewWidth = 0;
private int postion = 0;
private int posoffset = 0;
private int viewnum = 0;
public MyViewG(Context context, AttributeSet attrs) {
super(context, attrs);
mscroller = new Scroller(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.e(TAG,"onLayout");
//得到 viewgroup中存在的view的个数和 得到具体的view对象
for(int i = 0;i < getChildCount();i++){
View view = getChildAt(i);
view.layout(i * getWidth(), 0, getWidth() * (i + 1), getHeight());
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.e(TAG,"onMeasure");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
getChildAt(0).measure(widthMeasureSpec, heightMeasureSpec);
viewWidth = getChildAt(0).getMeasuredWidth();
viewnum = getChildCount();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e(TAG,"onTouchEvent");
int newX = (int) event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(TAG,"onTouchEvent down");
break;
case MotionEvent.ACTION_MOVE:
if(mscroller.computeScrollOffset()){
newX = getScrollX();
}
int disx = newX - lastX;
if(disx > (viewWidth )){
posoffset = (postion % viewnum)*viewWidth;
postion ++;
}
Log.e(TAG,"onTouchEvent down:" + String.valueOf(posoffset));
break;
case MotionEvent.ACTION_UP:
Log.e(TAG,"onTouchEvent up");
break;
}
//return super.onTouchEvent(event);
return true;
}
@Override
public void computeScroll() {
super.computeScroll();
scrollTo(posoffset, 0);
invalidate();
}
}
onLayout: 本容器(该类自身的view/viewgroup的内部摆放情况)
onMeasure:本容器(该类自身的view/viewgroup的宽度和长度),其中 widthMeasureSpec 和 heightMeasureSpec 大小值由上一级容器 (view )传入(仅个人理解)
Scroller :滑动的位置;更新需要 computeScroll 函数 和 invalidate函数
onTouchEvent:触摸事件,注意要将 该函数中的返回值 设置为 return true;否则 MOVE 事件无效
2.mainActivity 函数
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myView = (MyViewG) findViewById(R.id.myView);
int[] ids = new int[] { R.drawable.p_1, R.drawable.p_2,
R.drawable.p_3, R.drawable.p_5, R.drawable.p_6, R.drawable.p_7 };
for (int i = 0; i < ids.length; i++) {
ImageView imageView = new ImageView(this);
imageView.setBackgroundResource(ids[i]);
myView.addView(imageView);
}
}
3.layout 配置
<com.example.admin.myviewgroup.MyViewG
android:id="@+id/myView"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</com.example.admin.myviewgroup.MyViewG>
参考内容:
1.https://blog.csdn.net/lanpy88/article/details/6697661
2.https://blog.csdn.net/mw_123456/article/details/49817607