fresh digitable

めんどくさかったなってことを振り返ったり振り返らなかったりするための記録

ViewPagerで表示するviewのclickがひろえないなと思ったら

Twitter公式クライアントの画像プレビューに限りなく近いものを作りたくて、ViewPagerにわたすFragmentの中でImageViewを作って、OnClickListenerをセットしてクリックイベントをとろうと思って次のように書いたのだが、だめだった。

@Override
public View onCreateView(LayoutInflater inflater,
                           @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  super.onCreateView(inflater, container, savedInstanceState);
  return new ImageView(getContext());
}

@Override
public void onStart() {
  super.onStart();
  getView().setOnClickListener(new View.OnClickListener(View view) {
    // immersiveな状態を解除したりUIを表示したりする
  });
}

stackoverflowで解決策を探していると、PagerAdapter.instantiateItem()をオーバライドしてその中でクリックリスナやタッチリスナをセットしろというアドバイスがあったので、onCreateViewの中でImageViewsetOnClickListenerしてから返したりして難を逃れたりしていたが、次のようにも書けた。

private ImageView imageView;

@Override
public View onCreateView(LayoutInflater inflater,
                           @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  super.onCreateView(inflater, container, savedInstanceState);
  this.imageView = new ImageView(getContext());
  return this.imageView;
}

@Override
public void onStart() {
  super.onStart();
  this.imageView.setOnClickListener(new View.OnClickListener(View view) {
    // immersiveな状態を解除したりUIを表示したりする
  });
}

onStartでセットしてonStopで解除すれば生存期間が若干短くなるのでこっちの方がいいかなと思いました(こなみ)。

ただ、これだとimmersive modeから復帰するための「システムUIを引っ張り出すスワイプ」でも、指を離したときにクリックイベントがなぜか発生してしまうので、独自実装したタッチリスナを同様に渡したほうがよい。