Android LayoutInflater не работает тихо для LinearLayout - PullRequest
1 голос
/ 08 января 2012

Я использую LayoutInflater, чтобы получить представление из ресурсов, а затем вставить его в программно созданную пользовательскую ViewGroup. Это прекрасно работает, когда ресурс содержит только TextView. Но когда ресурс содержит LinearLayout, он тихо терпит неудачу - исключение не выдается, настраиваемые компоненты ViewGroup появляются, но View из ресурса не появляется.

Пользовательская ViewGroup помещает цветные рамки вокруг внутреннего View. Вот этот класс:

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. Вот метод Activity () 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." />

Выше работает нормально. На ней отображаются цветные рамки и текст «Вид из ресурса xml.».

Но он тихо завершается ошибкой, если файл ресурсов содержит LinearLayout. Вот метод Activity () 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 работать?

Я следовал за кодом inflater из XML Inflater, не видя ни одного из представлений? . Я удалил некоторые аргументы из инфляции, потому что они вызывают ошибки уже родителя. TextView работает без них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...