133

私が現在開発している Android アプリには、かなり大きくなったメイン アクティビティがあります。これは主に、TabWidget3 つのタブを持つ が含まれているためです。各タブにはかなりの数のコンポーネントがあります。アクティビティは、これらすべてのコンポーネントを一度に制御する必要があります。したがって、このアクティビティには約 20 のフィールド (ほぼすべてのコンポーネントのフィールド) があることが想像できると思います。また、多くのロジック (クリック リスナー、リストを埋めるロジックなど) も含まれています。

コンポーネント ベースのフレームワークで通常行うことは、すべてをカスタム コンポーネントに分割することです。その場合、各カスタム コンポーネントには明確な責任があります。独自のコンポーネントのセットと、そのコンポーネントに関連する他のすべてのロジックが含まれます。

これをどのように行うことができるかを理解しようとしたところ、Android のドキュメントで「複合コントロール」と呼ばれるものを見つけました。( http://developer.android.com/guide/topics/ui/custom-components.html#compoundを参照し、「複合コントロール」セクションまでスクロールします)構造を表示します。

ドキュメントには次のように書かれています。

アクティビティの場合と同様に、宣言型 (XML ベース) のアプローチを使用して含まれるコンポーネントを作成するか、コードからプログラムでネストすることができます。

それは朗報です!XML ベースのアプローチはまさに私が求めているものです! しかし、「アクティビティのように」ということを除いて、それを行う方法はわかりません...しかし、アクティビティで行うことは、setContentView(...)XMLからビューを膨らませるための呼び出しです。たとえば、サブクラスの場合、そのメソッドは使用できませんLinearLayout

そこで、次のように XML を手動で膨らませようとしました。

public class MyCompoundComponent extends LinearLayout {

    public MyCompoundComponent(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.my_layout, this);
    }
}

LinearLayoutロードしている XMLがルート要素として宣言されているという事実を除いて、これは機能します。これにより、膨張したものは、それ自体がすでに!!LinearLayoutである子になります。これで、間に冗長な LinearLayoutと実際に必要なビューができました。MyCompoundComponentLinearLayoutMyCompoundComponent

LinearLayout冗長なインスタンス化を回避して、これにアプローチするより良い方法を誰かが教えてくれますか?

4

2 に答える 2

102

XML ルートとしてマージタグを使用する

<merge xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Your Layout -->
</merge>

この記事をチェックしてください。

于 2009-09-25T11:07:57.397 に答える
0

あなたがやるべきことは、クラス名をXMLルート要素として使用することだと思います:

<com.example.views.MyView xmlns:....
       android:orientation="vertical" etc.>
    <TextView android:id="@+id/text" ... />
</com.example.views.MyView>

そして、使用したいレイアウトからクラスを派生させます。この方法を使用している場合、ここではレイアウト インフレータを使用しないことに注意してください。

public class MyView extends LinearLayout
{
    public ConversationListItem(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }
    public ConversationListItem(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }


    public void setData(String text)
    {
        mTextView.setText(text);
    }

    private TextView mTextView;

    @Override
    protected void onFinishInflate()
    {
        super.onFinishInflate();

        mTextView = (TextView)findViewById(R.id.text);
    }
}

その後、ビューを XML レイアウトで通常どおり使用できます。プログラムでビューを作成したい場合は、自分でインフレートする必要があります。

MyView v = (MyView)inflater.inflate(R.layout.my_view, parent, false);

残念ながらv = new MyView(context)、ネストされたレイアウトの問題を回避する方法がないように思われるため、これではできません。これは実際には完全な解決策ではありません。次のようなメソッドを追加しMyViewて、少し良くすることができます。

public static MyView create(Context context)
{
    return (MyView)LayoutInflater.fromContext(context).inflate(R.layout.my_view, null, false);
}

免責事項:私は完全なボロックを話しているかもしれません.

于 2012-10-22T15:53:23.403 に答える