23

アプリケーションで各アクティビティのカスタム タイトル ビューを使用しています。アクティビティの 1 つで、ボタンのクリックに基づいて、カスタム タイトル ビューを変更する必要があります。これで、setFeatureInt を呼び出すたびに問題なく動作します。

しかし、カスタム タイトルの項目を更新しようとしても (ボタンのテキストやタイトルのテキスト ビューを変更するなど)、更新は行われません。

コードをデバッグすると、テキスト ビューとボタン インスタンスが null ではないことがわかり、カスタム タイトル バーも表示されます。ただし、テキスト ビューまたはボタンのテキストは更新されません。他の誰かがこの問題に直面しましたか? どうすれば解決できますか?

ありがとう。

編集

これが私が試したものです。postInvalidate を呼び出しても更新されません。

    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.text_title);

    TextView databar = (TextView) findViewById(R.id.title_text);
    databar.setText("Some Text");
    databar.postInvalidate();

    Button leftButton = (Button) findViewById(R.id.left_btn);
    leftButton.setOnClickListener(mLeftListener);
    leftButton.setText("Left Btn");
    leftButton.postInvalidate();

    Button rightBtn = (Button) findViewById(R.id.right_btn);
    rightBtn.setOnClickListener(mRightListener);
    rightBtn.postInvalidate();
4

4 に答える 4

32

問題は、唯一のWindow実装 ( PhoneWindow)LayoutInflaterがそのsetFeatureIntメソッドで a を使用し、新しいレイアウトをinflateandでインスタンス化することattachToRoot=trueです。したがって、 を呼び出すsetFeatureIntと、新しいレイアウトは置き換えられませんが、内部のタイトル コンテナーにアタッチされ、互いの上に描画されます。

の代わりに次のヘルパー メソッドを使用することで、これを回避できますsetFeatureInt。ヘルパーは、新しいカスタム タイトル機能が設定される前に、内部タイトル コンテナーからすべてのビューを単純に削除します。


private void setCustomTitleFeatureInt(int value) {
    try {
        // retrieve value for com.android.internal.R.id.title_container(=0x1020149)
        int titleContainerId = (Integer) Class.forName(
            "com.android.internal.R$id").getField("title_container").get(null);

        // remove all views from titleContainer
        ((ViewGroup) getWindow().findViewById(titleContainerId)).removeAllViews();

        // add new custom title view 
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, value);

    } catch(Exception ex) {
        // whatever you want to do here..
    }
}

現在のsetFeatureInt動作が意図されたものかどうかはわかりませんが、何らかの形で文書化されていないことは確かです。そのため、これを Android 開発者に伝えます ;)

編集

コメントで指摘されているように、前述の回避策は理想的ではありません。定数に頼る代わりに、新しいタイトルを設定するたびに古いカスタム タイトルを非表示com.android.internal.R.id.title_containerにすることができます。

2 つのカスタム タイトル レイアウトがあるとします。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/custom_title_1" ...

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/custom_title_2" ...

に置き換えたい場合custom_title_1は、前者を非表示にして後者を追加するためにcustom_title_2使用できます。setFeatureInt

findViewById(R.id.custom_title_1).setVisibility(View.GONE);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_2);
于 2009-05-14T22:27:43.090 に答える
14

これを行う正しい方法は次のとおりです。

requestWindowFeature( Window.FEATURE_CUSTOM_TITLE );
setContentView( R.layout.my_layout );
getWindow().setFeatureInt( Window.FEATURE_CUSTOM_TITLE, R.layout.my_custom_title );
super.onCreate( savedInstanceState );

これらのステートメントの順序は非常に重要であることに注意してください。

他のステートメントの前にsuper.onCreate()を呼び出すと、空白のタイトルバーが表示されます。これは、タイトルバーIDを見つけて、そこからすべてのビューを削除するハックで修正されますが、お勧めしません。

于 2011-06-24T19:06:49.593 に答える
0

テキストを更新した後にビューを再描画するためにinvalidateまたはpostInvalidateを呼び出していますか?カスタムビューの場合、描画コードにブレークポイントを設定して、呼び出されることを確認できますか?

UIスレッドを使用している場合は、「invalidate」を呼び出すことができます。そうでない場合は、「postInvalidate」を呼び出す必要があります。そうしないと、ビューが再描画されません。

于 2009-05-05T16:41:11.060 に答える
0

ちょうど私の2cの価値:

MapActivity で作業しているときに、カスタム タイトルを要求すると、タイトルがまったく表示されませんでした。

幸いなことに、私がやりたかったことは、タイトル テキストを別の方法で設定することだけでした。すぐに、onCreate() 内で setTitle() を呼び出すだけでうまくいくことに気付きました (setContentView() を呼び出した後に呼び出しました)。

申し訳ありませんが、これ以上デバッグして、なぜ私がしていたことがうまくいかなかったのか、そしてなぜそれを変更するとうまくいったのかを理解する時間はありません. 私が言ったように、これは将来誰かを助けるかもしれないと思っただけです.

于 2010-01-09T01:36:29.210 に答える