我正在使用LayoutInflater从资源中检索视图,然后将其插入到程序化构造的自定义ViewGroup中。当资源仅包含TextView时,它工作正常。但是当资源包含LinearLayout时,它会安静地失败 - 不会抛出异常,会出现自定义ViewGroup组件,但不会显示资源中的View。
自定义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时,它工作正常。这是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工作?
我遵循了XML Inflater not seeing any of the views?的inflater代码。我从通货膨胀中删除了一些论点,因为它们导致了已经存在的父母错误。 TextView在没有它们的情况下工作。