在android上開發乙個左右側滑的元件,需要先了解以下知識
android中view繪製流程以及invalidate()等相關方法分析
使用scroller實現橫滑
android事件傳遞機制
先上圖,看看demo
左邊view顯示:
右邊view顯示
原始碼如下
package com.wan.ui.view;
import android.content.context;
import android.util.attributeset;
import android.util.log;
import android.util.typedvalue;
import android.view.motionevent;
import android.view.velocitytracker;
import android.view.view;
import android.view.viewconfiguration;
import android.view.viewgroup;
import android.widget.scroller;
public class flipperlayout extends viewgroup
public flipperlayout(context context, attributeset attrs)
public flipperlayout(context context, attributeset attrs, int defstyle)
@override
protected void onmeasure(int widthmeasurespec, int heightmeasurespec)
} public void setleftview(view leftview, layoutparams params)
} public void setrightview(view rightview, layoutparams params)
} public void setmasterview(view masterview, layoutparams params)
} private void initdata(context context)
@override
protected void onlayout(boolean changed, int l, int t, int r, int b)
@override
public void computescroll() }
// 分發事件
@override
public boolean dispatchtouchevent(motionevent ev)
// to close right 當rightview可見,且x <= mwidth ,則有可能觸發關閉rightview
if (mscreenstate == screen_state_right_open && x <= mwidth)
} else
return false;
break;
case motionevent.action_move:
// to close left
if (mscrollstate == scroll_state_allow && getwidth() - (int) ev.getx() < mwidth && mscreenstate == screen_state_left_open)
// to close right
if (mscrollstate == scroll_state_allow && ev.getx() < mwidth && mscreenstate == screen_state_right_open)
break;
case motionevent.action_cancel:
case motionevent.action_up:
releasevelocitytracker();
break;
default:
break;
} return super.dispatchtouchevent(ev);
} @override
public boolean onintercepttouchevent(motionevent ev)
break;
case motionevent.action_move:
final float dx = x - mlastmotionx;
if (mscrollstate == scroll_state_no_allow) }}
// 判斷橫滑的方向,通過移動方向來設定leftview 和rightview的顯示
monclick = false;
mvelocitytracker.computecurrentvelocity(1000, viewconfiguration.getmaximumflingvelocity());
if (mscrollstate == scroll_state_allow && math.abs(mvelocitytracker.getxvelocity()) > 200) else if (dx < 0 && mscreenstate == screen_state_close)
return true;
}break;
case motionevent.action_cancel:
case motionevent.action_up:
releasevelocitytracker();
break;
default:
break;
} return super.onintercepttouchevent(ev);
} @override
public boolean ontouchevent(motionevent ev)
break;
case motionevent.action_move:
if (!monclick)
break;
case motionevent.action_cancel:
case motionevent.action_up:
// action_up 和action_cancel 的時候,通過之前mwillstate的值和mscrollstate,處理最後view的滾動效果。
if (monclick)
if (mscrollstate == scroll_state_allow) else if (mwillstate == screen_state_right_open && mscreenstate == screen_state_close) else if (mwillstate == screen_state_left_close && mscreenstate == screen_state_left_open) else if (mwillstate == screen_state_right_close && mscreenstate == screen_state_right_open) else
}releasevelocitytracker();
break;
default:
break;
} return super.ontouchevent(ev);
} private void obtainvelocitytracker(motionevent event)
mvelocitytracker.addmovement(event);
} private void releasevelocitytracker()
} private void openleftview(int duration)
} public void openleftview()
private void closeleftview(int duration)
public void closeleftview()
public void openrightview(int duration)
} public void openrightview()
public void closerightview(int duration)
public void closerightview()
public int getleftwidth()
}
左右側滑原理與實現方式
左右側滑的原理在於把左邊的vc.view,右邊的vc.view和主檢視控制器的view加到同乙個vc。view上去,為主檢視控制器的view加上拖拽和單點手勢,做相應的處理控制相應的試圖的frame就可以了。好了,下面我們來自己試試。第一步 為容器檢視控制器宣告乙個方法 instancetype i...
移動端左滑右滑元件
很久沒發布文章了,一方面工作原因,一方面是惰性開始出來了。希望能繼續堅持菜雞之路。最近有個需求,移動端有導航,需要左滑右滑的時候就能切換導航,跟輪播一樣的效果,但是輪播內容少,而且是一次性載入資料。而需求是很多態別,每個型別有非常多的列表,如果使用輪播,一次性載入資料太多,再加上分頁,那就完全行不通...
有向線段的左右側界定
向量積的定義為 詳見維基百科 叉積可以定義為 在這裡 表示 假如兩個向量是在座標軸平面內,比如xy軸平面內,那麼這兩個向量積的方向即為z軸,或者正向,或者負向。沿著向量的方向界定左側和右側,乙個向量與其左側向量的叉積和與其右側向量的叉積是反向的。我們可以利用這一特點來判斷一條有向線段在另一條有向線段...