33093


各画面で共通の右スワイプ処理を、各画面の親ViewGroupのonTouchメソッド内に記述しています。  
TableLayoutやListViewを配置した画面では右スワイプ機能をきちんと動作させることができているのですが、  
LinearLayoutに1つのTextViewを画面いっぱいに配置した(width、heightともmatch_parent)画面では、onTouchが呼ばれません。  
試しにTextViewのサイズを小さくしてみて、TextViewの外側をタップすると正しくonTouchが呼ばれましたので、TextViewがブロックしているものと思うのですが、TextView上のタッチイベントを背景にそのまま投げるにはどのようにしたらよいでしょうか？  
(右スワイプ機能がきちんと動作しているTableLayoutやListViewを配置した画面でもTextViewが乗っかっているので、もしかしたらonTouchが呼ばれないのはまた別の原因かもしれません。)

TextView自体のonTouchに機能を実装する方法でもいいのですが、TextViewではイベントを無視して下のレイヤーにイベントをそのまま投げるような仕組みがあるかも？(あったら嬉しい)と思い質問いたしました。  
どうぞよろしくお願いいたします。

恥ずかしながら、以下コードです。まずは問題の画面のコード。

[code]

    //==============================================================================
    // 画面起動　最初のアクティビティ
    //==============================================================================
    public class A990_License extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.act_990);
        }
    }
    
    //==============================================================================
    // TextViewでいっぱいのフラグメント(B000_BaseFragmentを継承)
    //==============================================================================
    public class F990_License extends B000_BaseFragment {
    
        private static final String SELF_ID = "990";
        private static final int MAIN_LAYOUT_ID = R.layout.frg_990;
        private static final int BG_LAYOUT_ID = R.id.f990;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            mSelfID = SELF_ID;
            mMainLayoutID = MAIN_LAYOUT_ID;
            mBGLayoutID   = BG_LAYOUT_ID;
            super.onCreate(savedInstanceState);
        }
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
    
            //ライセンス文字列を表示
            TextView lblLicense = (TextView) getActivity().findViewById(R.id.lblLicense);
            lblLicense.setText("〜〜〜〜〜〜");
            //lblLicense.setOnTouchListener(this); //これでもいいけれど...
        }
    }
    
    //==============================================================================
    // 上記フラグメントの親クラス
    //==============================================================================
    public abstract class B000_BaseFragment extends Fragment implements View.OnTouchListener {
    
        protected int mMainLayoutID = 0;
        protected int mBGLayoutID = 0; //背景のビュー
        private GestureDetector mDetector; //ジェスチャー取得用
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            //ジェスチャー取得用オブジェクトを生成
            mDetector = new GestureDetector(getActivity(), new MyGestureListener());
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            if (mMainLayoutID != 0) {
                return inflater.inflate(mMainLayoutID, container, false);
            } else {
                return null;
            }
        }
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
    
            //オプションメニューを表示
            setHasOptionsMenu(true);
    
            if (mBGLayoutID > 0) {
                //背景にタッチイベントリスナー(右スワイプ)をセット
                ViewGroup viBG = (ViewGroup)getActivity().findViewById(mBGLayoutID);
                viBG.setOnTouchListener(this);
            }
        }
    
        /**************************************************
         * イベント処理(View.OnTouchListener)
         **************************************************/
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            debug("TextViewをタップした場合もここを通ってほしいの。");
            boolean ret = mDetector.onTouchEvent(event);
            return ret;
        }
    
        /**************************************************
         * ジェスチャー取得用インナークラス
         **************************************************/
        class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
    
            //X軸方向スワイプのmin距離
            private static final int SWIPE_MIN_DISTANCE = 100;
    
            @Override
            public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
                debug("swipe距離 " + (event2.getX() - event1.getX()));
                /// 右スワイプ
                if (event2.getX() - event1.getX() > SWIPE_MIN_DISTANCE) {
                    swipeRight();
                    return true;
                }
                return false;
            }
    
            @Override public boolean onDown(MotionEvent event) {
                return true;
            }
        }
    
        /// 右へスワイプイベント処理
        protected void swipeRight() {
            getActivity().finish(); //前画面に戻る
        }
    
    }
    
    //==============================================================================
    // act_990.xml(アクティビティのxml)
    //==============================================================================
    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             tools:context=".A990_License"
             android:layout_width="match_parent"
             android:layout_height="match_parent">
        <fragment class="〜.F990_License"
              android:id="@+id/f990"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>
    </FrameLayout>
    
    //==============================================================================
    // frg_990.xml(フラグメントのxml)
    //==============================================================================
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              tools:context=".F990_License"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
        <TextView
        android:id="@+id/lblLicense"
        android:autoLink="web"
        android:layout_width="match_parent"
        android:layout_height="match_parent" //--------ここを「wrap_content」にして実験した
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        android:background="#00ff00"
        />
    </LinearLayout>
    
[/code]

次は、期待通りにタッチイベントが取得できている画面のコードです。  
TableLayoutでTextView(`wrap_content`)も使用しています。

[code]

    //==============================================================================
    // 画面起動　アクティビティ
    //==============================================================================
    public class A940_Upd extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.act_940);
        }
    }
    
    //==============================================================================
    // TableLayoutを使ったフラグメント(こちらにもTextViewがあるが、想定の動きをしている)
    //==============================================================================
    public class F940_Upd extends B000_BaseInputFragment {
    
        private static final String SELF_ID = "940";
        private static final int MAIN_LAYOUT_ID = R.layout.frg_940;
        private static final int MENU_LAYOUT_ID = 0;
        private static final int BG_LAYOUT_ID = R.id.f940;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            mSelfID = SELF_ID;
            mMainLayoutID = MAIN_LAYOUT_ID;
            mMenuLayoutID = MENU_LAYOUT_ID;
            mBGLayoutID   = BG_LAYOUT_ID;
            super.onCreate(savedInstanceState);
        }
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            //引数を取得
            //タイトル表示
        }
    }
    
    //==============================================================================
    // 上記フラグメントの親クラス
    //==============================================================================
    public abstract class B000_BaseInputFragment extends B000_BaseFragment 
        implements TextWatcher, LoaderManager.LoaderCallbacks<MyCellData.List> {
    
        /**************************************************
         * イベント処理(View.OnTouchListener)
         **************************************************/
        /// タッチ時処理
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            if (super.onTouch(view, event)) {
                return true; //親側でイベント処理を終えた場合
    
            } else {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        return true;
                    case MotionEvent.ACTION_UP:
                        //背景がタップされたらキーボードを隠す
                        if (view.getId() == mBGLayoutID) {
                            AAA.closeKeyboard(view);
                            return true;
                        }
                        break;
                }
            }
            return false;
        }
    
        /**************************************************
         * イベント処理(TextWatcher)
         **************************************************/
        //〜省略〜
    
        /**************************************************
         * LoaderManager.LoaderCallbacks<>
         **************************************************/
        //〜省略〜
    }
    
    
    //==============================================================================
    // act_940.xml(アクティビティのxml)
    //==============================================================================
    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 xmlns:tools="http://schemas.android.com/tools"
                 tools:context=".A940_Upd"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent">
        <fragment class="〜.F940_Upd"
                  android:id="@+id/f940"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"/>
    </FrameLayout>    
    
    //==============================================================================
    // frg_940.xml(フラグメントのxml)
    //==============================================================================
    <?xml version="1.0" encoding="utf-8"?>
    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:layout_width="match_parent" android:layout_height="wrap_content"
                 android:background="#cccccc">
    
        <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"
                  android:minHeight="?attr/listPreferredItemHeight"
                  android:gravity="center_vertical"
                  android:paddingStart="?android:attr/listPreferredItemPaddingStart"
                  android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
                  android:layout_marginBottom="0.2dp"
                  android:background="#ffffff">
    
            <TextView android:id="@+id/lbl"
                      android:labelFor="@+id/txtTel"
                      android:layout_width="wrap_content" android:layout_height="wrap_content"
                      android:text="Tel"/>
    
            <EditText android:id="@+id/txtTel"
                      android:layout_width="wrap_content" android:layout_height="wrap_content"
                      android:layout_weight="1"
                      android:layout_marginStart="10dp"
                      android:layout_marginEnd="10dp"
                      android:maxLines="1"
                      android:inputType="phone"/>
    
            <ImageButton android:id="@+id/btnTel"
                         android:layout_width="wrap_content" android:layout_height="wrap_content"
                         android:src="@mipmap/ic_call_black_24dp"
                         android:background="@null"
                         android:contentDescription="Dial"/>
        </TableRow>
    </TableLayout>
    
[/code]


CC BY-SA 3.0
2017-03-03T08:16:21.097
33062
2017-03-04T11:14:20.270
2017-03-03T12:20:52.537
question
android java
親ViewGroupに設定したonTouchメソッドが呼び出されない


<http://blog.lciel.jp/blog/2013/12/03/android-touch-event/>  
こちらの記事が参考になると思います。  
既に一読済みでしたらすみません。


CC BY-SA 3.0
2017-03-03T08:25:19.503
33064
2017-03-03T08:25:19.503
20747
33062
answer


一応回答として残します。

`TextView`は`autoLink`の指定や、`Editable`の指定などがあると`TextView`自体がタッチイベントをハンドルすることがあります。  
`TextView`がイベントをハンドルしてしまった場合は親の`View`にはタッチイベントは通知されません。


CC BY-SA 3.0
2017-03-04T11:14:20.270
33093
2017-03-04T11:14:20.270
20272
33062
answer