2012-07-01 28 views
7

Cho bất kỳ hình dạng nào (hình tròn, ngôi sao, hình tam giác, bitmap có vùng trong suốt, v.v.) Tôi muốn biết nếu có thể (sử dụng API Android mới nhất) để biết người dùng đã nhấp hay chưa trên tầm nhìn, hoặc bên ngoài nó.Hình dạng tùy chỉnh thực của nút

Ví dụ: nếu tôi có nút tròn, tôi muốn biết liệu người dùng đã nhấp vào bên trong vòng kết nối hay không, nhưng không phải bên ngoài vòng kết nối đó.

Có thể không?

Nếu không, có thể tôi có thể thăm dò điểm ảnh của sự kiện chạm và nếu nó trong suốt, bỏ qua nó và nếu không, hãy xử lý nó dưới dạng sự kiện nhấp?

Trả lời

1

ok, tôi đã tìm được giải pháp làm việc cho mọi loại chế độ xem.

một số ghi chú:

  • buồn bã nó sử dụng một bitmap kích thước của các quan điểm, nhưng chỉ trong một khoảng nhỏ của thời gian.

    sau đó, nó giữ vị trí được xem xét trên khu vực hiển thị và được xem ở bên ngoài khu vực hiển thị.

  • tôi có thể làm cho bộ nhớ thân thiện hơn bằng cách tạo một mảng các số nguyên có cờ. hiện tại nó là một mảng boolean đơn giản.

  • tôi có thể kiểm tra giá trị alpha của bitmap trong JNI thay thế và tránh thời gian (ngắn) nơi tôi có cả bitmap và mảng cùng nhau.

  • nếu có ai đó có thể giúp cải thiện, điều đó thực sự tuyệt vời.

đây là các mã:

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); 
    } 
    } 

trong trường hợp IMAGExem đã thiết lập chiều rộng của nó & chiều cao để wrap_content, và nó thực sự có kích thước cần thiết, chỉ sau đó bạn có thể sử dụng Adnan Zahid solution, mà có thể là được viết theo cách này:

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; 
      } 
     }); 
    } 
    } 
2

Tôi cũng muốn làm điều gì đó tương tự và tôi đã kết thúc chỉnh sửa với FrameLayout. FrameLayout cho phép bạn thêm nhiều chế độ xem trên đầu trang của nhau.

Thêm FrameLayout. Bên trong đó bạn có thể thêm một 'Xem' và thiết lập chiều cao và chiều rộng của nó thành match_parent. Ở đầu Chế độ xem, thêm các nút bạn muốn.

Sau đó, trong mã của bạn, hãy tham khảo Chế độ xem và đặt trênClickListener trên đó để bất cứ khi nào người dùng chạm vào Chế độ xem đó, bạn có thể xử lý sự kiện đó. Đặt trình nghe nhấp chuột trên các nút khác.

Bây giờ, chỉ cần xử lý các sự kiện chạm của bạn. Bây giờ bạn sẽ biết nếu người dùng đã nhấp vào nút hoặc bên ngoài nút đó (người dùng đã nhấp vào Chế độ xem).

Nếu bạn muốn tạo các nút trong suốt hoặc mờ, hãy kiểm tra https://stackoverflow.com/a/11689915/1117338. Tôi hy vọng điều này sẽ hữu ích.

1
@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; 
     } 
    }); 
} 
8
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; 
} 

Bằng cách này bạn có thể nhận được giá trị alpha của pixel chạm. Bây giờ bạn có thể dễ dàng kiểm tra xem điểm ảnh được chạm vào trong suốt hay không.

+0

điều này thực sự có vẻ đầy hứa hẹn! tôi sẽ cần phải kiểm tra xem nó ra trước khi tôi đánh dấu câu trả lời của bạn, mặc dù. có thể có vấn đề: điều gì sẽ xảy ra trên các màn hình thiết bị khác nhau (mật độ/độ phân giải khác nhau)? nó vẫn sẽ hoạt động? Ngoài ra, hiện phương pháp này sử dụng bộ nhớ nhiều hơn theo cách này cho bitmap? –

+0

cũng có thể hoạt động ngay cả khi tôi không sử dụng bitmap để hiển thị trong chế độ xem không? –

+0

Nếu bạn đang thiết kế cho các màn hình khác nhau, bạn vẫn phải sử dụng các mảnh vỡ. Và đối với bitmap, tôi nghĩ rằng sử dụng một hình ảnh nút đồng bằng sẽ không sử dụng nhiều bộ nhớ vì nó có thể dễ dàng được thu nhỏ mà không làm mất nhiều chi tiết. Cuối cùng, có, bạn có thể sử dụng phương pháp drawbitmap nhưng điều đó sẽ yêu cầu một canvas vì vậy tôi khuyên bạn nên sử dụng một imageview thay thế. –

Các vấn đề liên quan