あるViewが他のViewを再描画する
fragment にカスタム View を配置し、もう一つの fragment にその View を操作する カスタム View を配置した。
しかし、片方の View の中を invalidate() で再描画しても全体の View は再描画されなかった。
アプリ全体を再描画するものだと思っていたけど、違ったらしい。
MainActivity の layout はこうなっている。
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:weightSum="4"></LinearLayout> </android.support.constraint.ConstraintLayout>
ここに、MainActivity から、2つの Fragment (BeChangeFragment, operateFragment) を LinearLayout に追加している。
うちの環境では、こうやって動的に追加しないとなぜかアプリが落ちる。
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(savedInstanceState == null){ FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.replace(R.id.linearLayout, new BeChangeFragment()); transaction.add(R.id.linearLayout, new OperateFragment()); transaction.commit(); } setColors(); } }
この BeChangeFragment の View の内容が operateFragment の View を操作したときに変更されるので、
operateFragment の View を操作したときに、BeChangeFragment の View を再描画する必要がある。
Fragment の Layout は、
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/linearLayout2" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"> <com.example.name.FragmentTest.BeChangeFragmentView android:id="@+id/be_change_fragment_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/linearLayout2" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"> <com.example.name.FragmentTest.OperateFragmentView android:id="@+id/operate_fragment_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
となっており、それぞれカスタム View の BeChangeFragmentView, OperateFragmentView を
取り込んでいる。二つの View (それを含む Fragment も) MainActivity の layout の中で同じ ViewGroup の
LinearLayout に属しているので、そこから、BeChangeFragmentView を取り出し invalidate() を呼び出し
再描画している。上記の操作をするためには、
public class OperateFragmentView extends View { @Override public boolean onTouchEvent(MotionEvent event){ switch(event.getAction()){ case MotionEvent.ACTION_DOWN: // lisner かなんかで変更をBeChangeFragmentView に伝える break; case MotionEvent.ACTION_UP: // lisner かなんかで変更をBeChangeFragmentView に伝える break; } invalidate(); // 自分の View の再描画 getRootView().findViewById(R.id.be_change_fragment_view).invalidate(); // BeChangeFragmentView の再描画 return true; } }
と、ラストの方で、getRootView()で自分の属する ViewGroup を取得して、findViewById でBeChangeFragmentView を
ゲット、やったぜ。
Fragment とか、MainActivity のl ayout 静的に配置するとアプリが落ちて、半日以上はまったけど、できるようになってきた。
ここら辺の描画の仕方とか、タッチの処理とか システムがどう処理しているのか、View とか Fragment がどういう場所で実行され、
なにが使えるのかとか、まだまだ全然わからないよ……。Fragment に View を配置しているのは再利用をしたいと思っているから
だけど、なんか複雑にしているだけの気もする。