1. 程式人生 > >自定義ViewGroup實現瀑布流效果

自定義ViewGroup實現瀑布流效果

今天情人節,我卻在家裡看書寫程式碼,真屌絲啊哈~

回顧:ViewGroup的時間分發流程:

dispatchTouchEvent ----- onInterceptTouchEvent----- onTouchEvent

最外層的ViewGroup首先接收到觸控事件,然後遍歷他的子View或者ViewGroup,將觸控時間分發給包含觸控位置的子View,繼續下去,直到該事件被消費(1.某個View的onTouchEvent返回了true;2.設定了監聽並返回了true。這樣該View的dispatchTouchEvent也就返回了true即事件被該View消費)onInterceptTouchEvent會攔截事件往下層傳遞,即中斷事件傳到子View,會執行自己的onTouchEvent。

下面的效果以前看到過,實現的思路挺不錯的,算是對事件分發這些知識的實戰吧。


在第一個listview裡面上下滑動,由第一個listview分發事件。

在第二個listview裡面上面滑動,三個listview均分發事件,實現一次觸控的聯動效果。

在第二個listview裡面的下面上下滑動,由第二個listview分發事件。

在第三個listview裡面上下滑動,由第三個listview分發事件。

繼承LinearLayot,攔截觸控事件,由自己重新分發。

public boolean onInterceptTouchEvent(MotionEvent ev) {
		return true;
	}
public boolean onTouchEvent(MotionEvent event) {
		width = getWidth();
		eventX = (int) event.getX();
		childWidth = width / getChildCount();
		if (eventX < childWidth) {
			// 第一列的listview
			event.setLocation(childWidth/2, event.getY());
			getChildAt(0).dispatchTouchEvent(event);
		}else if (eventX >childWidth && eventX < 2*childWidth) {
			// 第二列的listview
			event.setLocation(childWidth/2, event.getY());
			if (event.getY() < getHeight()/2) {
				// 第二列的listview上面
				// 三個listview聯動
				for(int i = 0; i < getChildCount(); i++){
					getChildAt(i).dispatchTouchEvent(event);
				}
			}else {
				// 第二列的listview下面
				getChildAt(1).dispatchTouchEvent(event);
			}
		}else {
			//第三列listview
			event.setLocation(childWidth/2, event.getY());
			getChildAt(2).dispatchTouchEvent(event);
		}	
		return super.onTouchEvent(event);
	}

佈局檔案:

<com.example.day150214_pullstream.MyLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="true" >

	<ListView 
	    android:id="@+id/lv1"
	    android:layout_height="match_parent"
	    android:layout_width="0dp"
	    android:layout_weight="1"
	    />
	<ListView 
	    android:id="@+id/lv2"
	    android:layout_height="match_parent"
	    android:layout_width="0dp"
	    android:layout_weight="1"
	    />
	<ListView 
	    android:id="@+id/lv3"
	    android:layout_height="match_parent"
	    android:layout_width="0dp"
	    android:layout_weight="1"
	    />
    
</com.example.day150214_pullstream.MyLayout>

MainActivity:

protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initList();
		adapter = new SimpleAdapter(this, list, R.layout.item, new String[]{"iv"}, new int[]{R.id.iv});
		lv1 = (ListView) findViewById(R.id.lv1);
		lv2 = (ListView) findViewById(R.id.lv2);
		lv3 = (ListView) findViewById(R.id.lv3);
		lv1.setAdapter(adapter);
		lv2.setAdapter(adapter);
		lv3.setAdapter(adapter);
	}

	
	private void initList() {
		for (int i = 0; i < 20; i++) {
			HashMap<String, Object> map = new HashMap<String, Object>();
			map.put("iv", R.drawable.ic_launcher);
			list.add(map);
		}
	}