6

處理的多個視圖從下面的圖像考慮的例子中,同時觸摸事件的Android

enter image description here

我正在尋找一個解決方案,查看通過觸摸事件從畫布到Viewpager。這對於在兩個視圖中同時應用相同數量的縮放都是必需的。

這裏是發生了什麼事情的技術說明,

(讓我們考慮的視圖一個 & Ç

A.父視圖

B.查看

C.查看傳呼機

dispatchTouchEvent()之前被稱爲對孩子( & Ç),該A.dispatchTouchEvent()將首先調用A.onInterceptTouchEvent( )以查看視圖組是否有興趣攔截事件。

所以,如果A.onTouchEvent()回報,那麼它可以追溯到高達B.onTouchEvent()。如果返回則返回到C.onTouchEvent()並且調度繼續照常進行。

而且回國後真正

  1. ACTION_CANCEL將被分派到所有的孩子們。

  2. 所有後續手勢事件(直到ACTION_UP/ACTION_CANCEL)將由如果定義,否則事件處理A.onTouchEvent事件偵聽器(OnTouchListener.onTouch())被消耗()在A的水平。

在這一點上我可以通過從父事件對孩子的看法,但不能讓孩子2視圖。 & C一起處理事件(在兩個視圖上應用相同數量的縮放)。

有沒有辦法將觸摸事件從父視圖傳遞給子視圖,以便他們可以同時處理事件?

這是我的佈局設置,

<RelativeLayout 
    android:id="@+id/layoutParent" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#FFFFFFFF"> 

      <com.androidapp.NonSwipeableViewPager 
       android:id="@+id/pager" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_gravity="center" 
       android:background="@color/transparent" /> 

      <com.androidapp.DrawingView 
       android:id="@+id/drawing" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:background="@color/transparent" /> 

</RelativeLayout> 
+0

畫布是如何定位在viewpager控制?它顯示爲彈出窗口還是其他方式? – ridoy

+0

畫布和viewpager在2個獨立的視圖內。仔細查看我的佈局代碼。@ridoy –

+0

因此,您的DrawingView攔截NonSwipeableViewPager(根據您的佈局代碼),不是嗎? – ridoy

回答

4

如果我沒有錯,您想要在頂部和底部視圖上處理相同的觸摸事件。根據Android觸摸架構,您無法同時處理來自多個視圖的觸摸事件。要麼您必須在onTouchEvent()方法內處理它,要麼傳遞到下一個視圖。您還需要等到頂視圖完成處理MotionEvent()並讓子視圖處理。

下面是使用RxAndroid方法,

一個可能的解決方案裏面你的畫布視圖的MotionEvent()

@Override 
    public boolean onTouchEvent(MotionEvent event) { 

    // process all touch events (UP/DOWN/MOVE) 

    //send events as observable 
    RxBus.getInstance().sendMotionEvent(event); 

    return true; 
} 

這將觀察到運動事件,並通知所有的觀察者。

現在,在您的viewpager的onResume()內預訂動作事件,以便每當從畫布進行更改時它都會立即傳遞事件。

Subscription RxBus _rxBus = RxBus.getInstance(); 
     subscription = _rxBus.getMotionEvent() 
       .subscribe(new Action1<MotionEvent>() { 
        @Override 
        public void call(MotionEvent event) { 
         // call the onTouchEvent of your widget e.g. ImageView and pass the received event 
         // this will apply the same touch event that was applied in the canvas 

         // .onTouchEvent(event) is important to override the onTouchEvent() of your widget that will use the touch event 
         imageView.onTouchEvent(event); 
        } 
      }); 

RxBus類如下,

public class RxBus { 

    private static RxBus instance; 

    private final PublishSubject<MotionEvent> motion_event = PublishSubject.create(); 

    public static RxBus getInstance() { 
     if (instance == null) { 
      instance = new RxBus(); 
     } 
     return instance; 
    } 

    public void sendMotionEvent(MotionEvent motionEvent) { 
     motion_event.onNext(motion_event); 
    } 

    public Observable<MotionEvent> getMotionEvent() { 
     return motion_event; 
    } 
} 
2

這是很容易通過回調來實現。只需用任何方法創建一個接口,然後在Viewpager中實現。調用將在您的View類中根據您的觸摸事件調用,並且響應將發送到Viewpager。我在MainActivity中創建了一個ImageView的示例,並調用它從另一個片段更改大小,並且它可以工作。這裏是我下面的代碼:

public interface ICallBackForResize { 
    void resizeme(); 
    void actionUp(); 
    void actionDown(); 

} 

MainActivity:

public class MainActivity extends AppCompatActivity implements ICallBackForResize { 

ImageView img; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    img= (ImageView) findViewById(R.id.image); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 

@Override 
public void resizeme() { 
    Toast.makeText(MainActivity.this,"called",Toast.LENGTH_LONG).show(); 
    img.getLayoutParams().height += 20; 
    img.getLayoutParams().width += 20; 
    img.requestLayout(); 
} 

@Override 
public void actionUp() { 
    //do whatever 
} 

@Override 
public void actionDown() { 
    //do whatever 

} 
} 

我的片段類與簡單的按鈕:

public class MyFragmentButton extends Fragment { 
View view; 
ICallBackForResize callBackForResize; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    callBackForResize= (ICallBackForResize) getActivity(); 
} 

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    view=inflater.inflate(R.layout.mybutton,container,false); 
    Button btn= (Button) view.findViewById(R.id.button); 
    btn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      callBackForResize.resizeme(); 
     } 
    }); 
    return view; 
} 
} 

我相信你不需要XML文件。如果有人需要我只是共享:

activity_main:

<?xml version="1.0" encoding="utf-8"?> 

<android.support.design.widget.AppBarLayout 
    android:layout_height="wrap_content" 
    android:layout_width="match_parent" 
    android:theme="@style/AppTheme.AppBarOverlay"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="?attr/actionBarSize" 
     android:background="?attr/colorPrimary" 
     app:popupTheme="@style/AppTheme.PopupOverlay" /> 

</android.support.design.widget.AppBarLayout> 

<include layout="@layout/content_main"/> 


</android.support.design.widget.CoordinatorLayout> 

content_main:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
android:paddingBottom="@dimen/activity_vertical_margin" 
app:layout_behavior="@string/appbar_scrolling_view_behavior" 
tools:showIn="@layout/activity_main" 
tools:context="nanofaroque.com.addlistener.MainActivity"> 

<ImageView 
    android:id="@+id/image" 
    android:text="Hello World!" 
    android:layout_width="100dp" 
    android:layout_gravity="center" 
    android:src="@mipmap/ic_launcher" 
    android:layout_height="100dp" /> 


<fragment 
    android:name="nanofaroque.com.addlistener.MyFragmentButton" 
    android:id="@+id/headlines_fragment" 
    android:layout_width="100dp" 
    android:layout_height="100dp" /> 

</FrameLayout> 

則myButton:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" android:layout_width="match_parent" 
android:layout_height="match_parent"> 
<Button 
    android:id="@+id/button" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

</LinearLayout> 
+0

感謝您的簡短回答,但是我有興趣同時在兩個視圖上處理觸摸事件(現在,如果我將觸摸事件從一個視圖傳遞到另一個視圖,它只是忽略頂級事件視圖)。請檢查更新後的問題。 –

+0

在這種情況下,我相信ChildView應該是獨立的佈局。相對佈局不會在這種情況下工作,因爲人們相對於其他人查看位置。感謝和好運。 –