いくつかのロジックを保持するカスタム複合コントロールを Android で作成したいと考えています。この例では、クリックしたときに 2 つのビューを切り替えるとします。
API ガイドによると、それを行う方法は、Layout を拡張する新しいクラスを作成し、そこですべてを行うことのようです。
だから私はちょうどそれをしました:
- カスタム コンポーネント用にインフレートする XML レイアウトを作成しました。
.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/view1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Hello"/>
<TextView
android:id="@+id/view2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="World"
android:visibility="gone"/>
</RelativeLayout>
次に、カスタム Layout クラスを作成し、そこにロジックを追加しました。
public class MyWidget extends RelativeLayout { public final View mView1; 公開最終ビュー mView2;
public MyWidget(Context context, AttributeSet attrs) { super(context, attrs); LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); RelativeLayout view = (RelativeLayout) inflater.inflate(R.layout.my_widget, this, true); mView1 = view.findViewById(R.id.view1); mView2 = view.findViewById(R.id.view2); view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { switchViews(); } }); } public void switchViews() { if (mView1.getVisibility() == View.VISIBLE) { mView1.setVisibility(View.GONE); } else { mView1.setVisibility(View.VISIBLE); } if (mView2.getVisibility() == View.VISIBLE) { mView2.setVisibility(View.GONE); } else { mView2.setVisibility(View.VISIBLE); } }
}
最後に、カスタム ビューをいくつかのレイアウトに含めました。
.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.example.MyWidget
android:layout_height="match_parent"
android:layout_width="match_parent"/>
</RelativeLayout
そして、それは機能します。
ただし、次の 2 つの理由から、このソリューションに完全に満足しているわけではありません。
MyWidget のコンストラクターで、コンストラクターを
RelativeLayout
呼び出してネストされた 2super()
つと、XML レイアウトのルートにあるものをインスタンス化します。そのために、代わりに XML ルートとして使用できることを知っているので<merge>
、余分なRelativeLayout
. タグなどで XML 属性を定義しても効果がないことを除いて、android:background
プログラム<merge>
で定義する必要がありますが、これはそれほど適切ではありません。カスタム ビューは RelativeLayout のサブクラスであるため、
addView()
子ビューを追加する意味がない場合でも、カスタム ビューから継承するメソッド ( など) を公開します。これらのメソッドをオーバーライドして、ユーザーがそれを行うのを防ぐことができることはわかっていますが、View から継承する方がよりクリーンであることがわかります。