給定任何形狀(實心圓,星形,三角形,帶有透明區域的位圖等)我想知道是否有可能(使用最新的Android API)知道用戶是否點擊過在視圖上,或在它之外。真正的自定義形狀的按鈕
例如,如果我有一個圓形按鈕,我想知道用戶是否在圓圈內點擊過,但不在圓圈外。
可能嗎?
如果沒有,也許我可以輪詢觸摸事件的像素,如果它是透明的,忽略它,如果不是,將它作爲點擊事件處理?
給定任何形狀(實心圓,星形,三角形,帶有透明區域的位圖等)我想知道是否有可能(使用最新的Android API)知道用戶是否點擊過在視圖上,或在它之外。真正的自定義形狀的按鈕
例如,如果我有一個圓形按鈕,我想知道用戶是否在圓圈內點擊過,但不在圓圈外。
可能嗎?
如果沒有,也許我可以輪詢觸摸事件的像素,如果它是透明的,忽略它,如果不是,將它作爲點擊事件處理?
好的,我發現任何類型的視圖的工作解決方案。
一些注意事項:
可悲的是它使用的視圖大小的位圖,但僅限於時間的少量。
之後,它會保留它在可見區域的考慮位置以及考慮在可見區域外的位置。
我可以通過製作一個具有標誌的整數數組來使其更加內存友好。目前它是一個簡單的布爾數組。
我可以在JNI中檢查位圖的alpha值,並避免讓(短)時間將位圖和數組放在一起。
如果任何人都可以幫助改善它,它可能會非常棒。
下面的代碼:
public class MainActivity extends Activity
{
boolean[] _inVisibleAreaMap;
private int _width,_height;
@Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final View view=findViewById(R.id.imageView1);
view.setDrawingCacheEnabled(true);
runJustBeforeBeingDrawn(view,new Runnable()
{
@Override
public void run()
{
final Bitmap bitmap=view.getDrawingCache();
_width=bitmap.getWidth();
_height=bitmap.getHeight();
_inVisibleAreaMap=new boolean[_width*_height];
for(int y=0;y<_width;++y)
for(int x=0;x<_height;++x)
_inVisibleAreaMap[y*_width+x]=Color.alpha(bitmap.getPixel(x,y))!=0;
view.setDrawingCacheEnabled(false);
bitmap.recycle();
}
});
view.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(final View v,final MotionEvent event)
{
final int x=(int)event.getX(),y=(int)event.getY();
boolean isIn=x>=0&&y>=0&&x<_width&&y<_height;
// if inside bounding box , check if in the visibile area
if(isIn)
isIn=_inVisibleAreaMap[y*_width+x];
if(isIn)
Log.d("DEBUG","in");
else Log.d("DEBUG","out");
return true;
}
});
}
private static void runJustBeforeBeingDrawn(final View view,final Runnable runnable)
{
final ViewTreeObserver vto=view.getViewTreeObserver();
final OnPreDrawListener preDrawListener=new OnPreDrawListener()
{
@Override
public boolean onPreDraw()
{
runnable.run();
final ViewTreeObserver vto=view.getViewTreeObserver();
vto.removeOnPreDrawListener(this);
return true;
}
};
vto.addOnPreDrawListener(preDrawListener);
}
}
的情況下的ImageView已設置其寬度&高度WRAP_CONTENT,它真正得到它所需要的尺寸,只有這樣,你可以使用Adnan Zahid solution,這可能是這樣寫:
public class MainActivity extends Activity
{
private int _width,_height;
@Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView image=(ImageView)findViewById(R.id.imageView1);
final Bitmap bitmap=((BitmapDrawable)image.getDrawable()).getBitmap();
_width=bitmap.getWidth();
_height=bitmap.getHeight();
image.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(final View v,final MotionEvent event)
{
final int x=(int)event.getX(),y=(int)event.getY();
boolean isIn=x>=0&&y>=0&&x<_width&&y<_height;
if(isIn)
{
final int pixel=bitmap.getPixel((int)event.getX(),(int)event.getY());
final int alphaValue=Color.alpha(pixel);
isIn=alphaValue!=0;
}
if(isIn)
Log.d("DEBUG","in");
else Log.d("DEBUG","out");
return true;
}
});
}
}
我也想做這樣的事情,我最終調整了FrameLayout。 FrameLayout允許您在彼此頂部添加多個視圖。
添加一個FrameLayout。在裏面你可以添加一個'View',並將其高度和寬度設置爲match_parent。在視圖之上,添加你想要的按鈕。
然後在您的代碼中,獲取視圖的引用並在其上設置onClickListener,以便每當用戶觸摸該視圖時,您都可以處理該事件。在其他按鈕上也設置點擊監聽器。
現在只需處理您的觸摸事件。您現在將知道用戶是否點擊了該按鈕或在該按鈕之外(用戶點擊了該視圖)。
如果您想創建透明或半透明按鈕,請檢查https://stackoverflow.com/a/11689915/1117338。 我希望這可以幫助。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FrameLayout root = (FrameLayout)findViewById(R.id.root);
root.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == ID){
// Your code
}
return true;
}
});
}
ImageView image=(ImageView) findViewById(R.id.imageView1);
image.setOnTouchListener(this);
Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int pixel = bitmap.getPixel((int)event.getX(), (int)event.getY());
int alphaValue=Color.alpha(pixel);
return true;
}
這樣你就可以得到感動像素的Alpha值。現在您可以輕鬆檢查所觸摸的像素是否透明。
這實際上看起來很有前途!不過,我需要先檢查一下,然後再選擇你的答案。可能會有問題:不同設備屏幕上會發生什麼(不同的密度/分辨率)?它會繼續工作嗎?此外,這種方法是否使用更多的內存這種方式的位圖? –
也,即使我不使用位圖顯示在視圖中它會工作嗎? –
如果你正在設計不同的屏幕,你必須使用碎片。至於位圖,我認爲使用普通按鈕圖像不會使用太多的內存,因爲它可以輕鬆縮放而不會損失太多細節。最後,是的,你可以使用drawbitmap方法,但這需要一個畫布,所以我建議使用imageview來代替。 –