1

LayoutInflater を使用してリソースからビューを取得し、それをプログラムで構築されたカスタム ViewGroup に挿入しています。リソースに TextView のみが含まれている場合は正常に機能します。ただし、リソースに LinearLayout が含まれている場合、静かに失敗します。例外はスローされず、カスタム ViewGroup コンポーネントは表示されますが、リソースからのビューは表示されません。

カスタム ViewGroup は、内側のビューの周りに色付きの境界線を配置します。クラスは次のとおりです。

package ask.question;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

public class BorderViewGroup extends ViewGroup {

    private View leftBorder ; 
    private View topBorder ; 
    private View rightBorder ; 
    private View bottomBorder ; 
    private View innerView = null ; 

    public BorderViewGroup(Context context) {
        super(context);
        initBorderViewGroup(context); 
    }

    public BorderViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
        initBorderViewGroup(context); 
    }

    public BorderViewGroup(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initBorderViewGroup(context); 
    }

    private void initBorderViewGroup(Context context) {
        leftBorder = new View(context); 
        topBorder = new View(context); 
        rightBorder = new View(context); 
        bottomBorder = new View(context); 
        addView(leftBorder); 
        addView(topBorder); 
        addView(rightBorder);
        addView(bottomBorder); 
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        // Should probably use argument 'changed'. 
        int width = r - l; 
        int height = this.getHeight(); 
        leftBorder.layout(0, 0, 2, height); 
        topBorder.layout(0, 0, width, 2); 
        rightBorder.layout(width-2, 0, width, height); 
        bottomBorder.layout(0, height-2, width, height); 
        if (innerView != null) { 
            innerView.layout(2, 2, width-2, height-2); 
        } 
    }

    /*
     * Sets the view to be displayed within the borders. 
     * Subsequent calls will replace the view. 
     * @param view View to be displayed. May be null. 
     */
    public void setInnerView(View view) {
        if (innerView!=null) { 
            this.removeView(innerView); 
        }
        this.innerView = view ; 
        if (innerView!=null) { 
            addView(innerView); 
        }
    }

    /*
     * Sets the colors for each of the four borders. 
     * A color value of zero will be ignored, leaving that border unchanged. 
     * Note: colors can be specified in hexadecimal. Red is 0xFFFF0000. In general, the first two hex digits control transparency, the next red, green and blue. 
     */
    public void setBorderColors(int leftColor, int topColor, int rightColor, int bottomColor) { 
        if (leftColor!=0) leftBorder.setBackgroundColor(leftColor); 
        if (topColor!=0) topBorder.setBackgroundColor(topColor); 
        if (rightColor!=0) rightBorder.setBackgroundColor(rightColor); 
        if (bottomColor!=0) bottomBorder.setBackgroundColor(bottomColor); 
    }

    /*
     * Sets the color of the border around the innerView. 
     * A color value of zero will be ignored, leaving the border unchanged. 
     * Note: colors can be specified in hexadecimal. Red is 0xFFFF0000. In general, the first two hex digits control transparency, the next red, green and blue. 
     */
    public void setBorderColor(int color) { 
        setBorderColors(color, color, color, color); 
    }

}

リソースが TextView の場合は正常に機能します。アクティビティの onCreate() メソッドと、リソース ファイル flat.xml を次に示します。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    BorderViewGroup bvg = new BorderViewGroup(this); 
    LayoutInflater inflater = LayoutInflater.from(this); 
    //View mainView = inflater.inflate(R.layout.flat, null); 
    View mainView = inflater.inflate(R.layout.nested, null); 
    View objectView = mainView.findViewById(R.id.object_view);
    if (mainView==null) throw new RuntimeException("mainView is null"); 
    if (objectView==null) throw new RuntimeException("objectView is null"); 
    bvg.setBorderColors(0xFFFF0000, 0xFF00F0F0, 0xFF00FF00, 0xFF0000FF); 
    setContentView(bvg); 
    bvg.setInnerView(objectView); 
}

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/object_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:text="View from resource xml." />

上記は正常に動作します。色付きの境界線と「View from resource xml.」というテキストが表示されます。

ただし、リソース ファイルに LinearLayout が含まれていると、静かに失敗します。アクティビティの onCreate() メソッドと、リソース ファイルの nested.xml を次に示します。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    BorderViewGroup bvg = new BorderViewGroup(this); 
    LayoutInflater inflater = LayoutInflater.from(this); 
    View mainView = inflater.inflate(R.layout.flat, null); 
    //View mainView = inflater.inflate(R.layout.nested, null); 
    View objectView = mainView.findViewById(R.id.object_view);
    if (mainView==null) throw new RuntimeException("mainView is null"); 
    if (objectView==null) throw new RuntimeException("objectView is null"); 
    bvg.setBorderColors(0xFFFF0000, 0xFF00F0F0, 0xFF00FF00, 0xFF0000FF); 
    setContentView(bvg); 
    bvg.setInnerView(objectView); 
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/object_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="A TextView from resource XML." />

    <TextView
        android:id="@+id/here"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="A second TextView." />


</LinearLayout>

これは動作しません。色付きの境界線は表示されますが、テキストは表示されません。

一方が機能し、もう一方が機能しないのはなぜですか? さらに良いことに、LinearLayout を機能させるにはどうすればよいでしょうか?

ビューが表示されない XML インフレータのインフレータ コードをたどりましたか? . すでに親がいるというエラーが発生するため、インフレからいくつかの引数を削除しました。TextView はそれらがなくても機能します。

4

0 に答える 0