如何正确充气XML-布局,文件中自定义的ViewGroup?自定义、如何正确、布局、文件

2023-09-12 10:53:18 作者:活着真没意思

我要夸大一个XML-布局,文件在自定义的ViewGroup类,我的问题是,它产生的只是一个空白屏幕。做同样的活动课工作正常。 这是我简单的XML-布局-文件:

  shownumberlayout.xml:

    < RelativeLayout的
        的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =FILL_PARENT
        机器人:后台=#FFFFFF
        机器人:ID =@ + ID / layoutForNumber>

        <的TextView
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =WRAP_CONTENT
            机器人:ID =@ + ID / tvNumber
            机器人:layout_centerHorizo​​ntal =真
            机器人:文字颜色=#000000
            机器人:文本=测试
            机器人:layout_centerVertical =真
            机器人:TEXTSIZE =30dip>
        < / TextView的>

    < / RelativeLayout的>
 

下面是工作版本,充气 shownumberlayout.xml 的活动 ShowNumber

  ShowNumber.class

公共类ShowNumber延伸活动{
    / **第一次创建活动时调用。 * /

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        LayoutInflater充气=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ViewGroup中VG =(ViewGroup中)inflater.inflate(R.layout.shownumberlayout,NULL);
        的setContentView(VG);
    }
}
 

这显示了一个白色背景上的黑色文字测试为中心。

自定义View在xml中无法使用

现在的版本的膨胀中的XML定制的ViewGroup 级轿车:

  ViewGroup.class
公共类ViewNumber扩展的ViewGroup {

    私人LayoutInflater充气;

    公共ViewNumber(上下文的背景下){
        超(上下文);
        // TODO自动生成构造函数存根
        initView(上下文);
    }

    公共ViewNumber(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
        // TODO自动生成构造函数存根
        initView(上下文);
    }

    公共ViewNumber(上下文的背景下,ATTRS的AttributeSet,诠释defStyle){
        超(背景下,ATTRS,defStyle);
        // TODO自动生成构造函数存根
        initView(上下文);
    }

    私人无效initView(上下文的背景下){
        充气=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.shownumberlayout,NULL);
    }

    @覆盖
    保护无效onLayout(布尔改变,诠释L,INT T,INT R,int b)在{
        // TODO自动生成方法存根
    }

}
 

ShowNumber.class 公共类ShowNumber延伸活动{     / **第一次创建活动时调用。 * /

  @覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    ViewGroup中VG =新ViewNumber(本);
    的setContentView(VG);
}
 

}

Im做它基本上​​就像在this答案解释。 这只是产生一个空的黑色屏幕。我做错了什么?

更新1

@Konstantin 我申请的变化,但仍然只是一个空白的屏幕,我也做了一个日志输出中获取的儿童人数。它仍然始终为1,连我增加一个TextView中以XML的布局文件中。变化之前,它始终保持0。

 公共类ViewNumber扩展RelativeLayout的{
...
私人无效initView(上下文的背景下){
        //充气=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //inflater.inflate(R.layout.shownumberlayout,NULL);
        View.inflate(背景下,R.layout.shownumberlayout,这一点);
        Log.v(ViewNumber,儿童数量:+ this.getChildCount()); //输出为1,但它仍然0之前
    }
...
}
 

@Sankar 这是logcat中,从康斯坦丁变化后:

  9月十二号至16日:24:23.606:DEBUG / AndroidRuntime(8951):>>>>>>>>>>> >>> AndroidRuntime START<<<<<<<<<<<<<<
9月12号至一十六号:24:23.606:DEBUG / AndroidRuntime(8951):CheckJNI为OFF
9月12号至一十六号:24:23.606:DEBUG / dalvikvm(8951):创建INSTR宽表
9月12号至一十六号:24:23.656:DEBUG / AndroidRuntime(8951):---注册本地函数---
9月12号至一十六号:24:23.916:DEBUG / AndroidRuntime(8951):关闭虚拟机
9月12号至一十六号:24:23.916:DEBUG / dalvikvm(8951):调试器分离;对象注册了1项
9月12号至一十六号:24:23.916:信息/ AndroidRuntime(8951):注:连接线的捆扎线#3'失败
12日至16 09:24:24.076:调试/ AndroidRuntime(8960):GT;>>>>>>>>>>>>> AndroidRuntime START<<<<<<<<<<<<<<
9月12号至一十六号:24:24.076:DEBUG / AndroidRuntime(8960):CheckJNI为OFF
9月12号至一十六号:24:24.076:DEBUG / dalvikvm(8960):创建INSTR宽表
9月12号至一十六号:24:24.126:DEBUG / AndroidRuntime(8960):---注册本地函数---
9月12号至一十六号:24:24.376:信息/ ActivityManager(78):启动活动:意向{行为= android.intent.action.MAIN猫= [android.intent.category.LAUNCHER] FLG = 0x10000000处CMP = org.customview。哈罗德/ .ShowNumber}
9月12号至一十六号:24:24.426:DEBUG / AndroidRuntime(8960):关闭虚拟机
9月12号至一十六号:24:24.426:DEBUG / JDWP(8960):GOT唤醒信号,救助的选择了
9月12号至一十六号:24:24.426:DEBUG / dalvikvm(8960):调试器分离;对象注册了1项
9月12号至一十六号:24:24.456:信息/ AndroidRuntime(8960):注:连接线的捆扎线#3'失败
9月12号至一十六号:24:24.456:VERBOSE / ViewNumber(8923):儿童的数量:1
9月12号至一十六号:24:24.496:VERBOSE / RenderScript_jni(164):surfaceDestroyed
9月12号至一十六号:24:24.526:信息/ ActivityManager(78):显示活动org.customview.harold / .ShowNumber:104毫秒(总104毫秒)
9月12号至一十六号:24:24.576:DEBUG / dalvikvm(158):GC_FOR_MALLOC释放10631对象/在52ms 526248字节
9月12号至一十六号:24:34.606:DEBUG / dalvikvm(164):GC_EXPLICIT释放1776对象/在91ms 106960字节
 

更新2

该内容最终显示出正确了。 缺少的东西是要覆盖的方法 onLayout (感谢法)在RelativeLayout的-Sublcass:

 公共类ViewNumber扩展RelativeLayout的{
...

    @覆盖
            保护无效onLayout(布尔改变,诠释L,INT T,INT R,int b)在{
                // TODO自动生成方法存根
                的for(int i = 0; I< getChildCount();我++){
                    getChildAt(ⅰ).layout(L,T,R,B);
                }
            }
...
}
 

注:后来你也应该覆盖的方法 onMeasurement(),但目前内容也呈现出不正确的覆盖它

现在的方法 initView 从溶液中的法未对齐的中心TextView的,但把它放在左上角。从溶液中的康斯坦丁正确地把它在视图的中心:

 公共类ViewNumber扩展RelativeLayout的{
...
私人无效initView(上下文的背景下){
        View.inflate(背景下,R.layout.shownumberlayout,这一点);
    }
...
}
 

解决方案

你试试这个?

 私人无效initView(上下文的背景下){
        充气=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.addView(inflater.inflate(R.layout.shownumberlayout,NULL));
    }
 

编辑:我迅速作出反应......一个ViewGroup中有ppare为子女布局责任$ P $,在布局方法试试这个:

  @覆盖
        保护无效onLayout(布尔改变,诠释L,INT T,INT R,int b)在{
            // TODO自动生成方法存根
            的for(int i = 0; I< getChildCount();我++){
                getChildAt(ⅰ).layout(L,T,R,B);
            }
        }
 

I want to inflate a XML-Layout-File in a custom ViewGroup Class, my Problem is that it produces just a empty screen. Doing the same in the Activity Class works fine. Here is my simple XML-Layout-File:

shownumberlayout.xml:

    <RelativeLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:background="#FFFFFF" 
        android:id="@+id/layoutForNumber">

        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:id="@+id/tvNumber"
            android:layout_centerHorizontal="true" 
            android:textColor="#000000" 
            android:text="Test" 
            android:layout_centerVertical="true" 
            android:textSize="30dip">
        </TextView>

    </RelativeLayout>

Here is the working Version, inflating the shownumberlayout.xml in the Activity ShowNumber:

ShowNumber.class

public class ShowNumber extends Activity {
    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ViewGroup vg = (ViewGroup) inflater.inflate(R.layout.shownumberlayout, null);
        setContentView(vg);
    }
}

This shows a White Background with the black Text "Test" centered.

Now the Version inflating the xml in the Custom ViewGroup-Class:

ViewGroup.class
public class ViewNumber extends ViewGroup {

    private LayoutInflater inflater;

    public ViewNumber(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        initView(context);
    }

    public ViewNumber(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        initView(context);
    }

    public ViewNumber(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
        initView(context);
    }

    private void initView(Context context){
        inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.shownumberlayout, null);  
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        // TODO Auto-generated method stub
    }

}

ShowNumber.class public class ShowNumber extends Activity { /** Called when the activity is first created. */

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ViewGroup vg = new ViewNumber(this); 
    setContentView(vg);
}

}

Im doing it basically like in this Answer explained. This just produces a Empty Black Screen. What I am doing wrong?

UPDATE 1

@Konstantin I applied your changes but still just a blank screen, i also made a log-ouput for getting the number of children. It remains always 1, even i add one more Textview to the XML-Layout-File. Before the Changes it remains always 0.

public class ViewNumber extends RelativeLayout {
...
private void initView(Context context){
        //inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //inflater.inflate(R.layout.shownumberlayout, null);
        View.inflate(context, R.layout.shownumberlayout,this); 
        Log.v("ViewNumber", "Number of Child: " + this.getChildCount());//output is 1,before it remains 0
    }
...
}

@Sankar This is the Logcat, after the Changes from Konstantin:

12-16 09:24:23.606: DEBUG/AndroidRuntime(8951): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
12-16 09:24:23.606: DEBUG/AndroidRuntime(8951): CheckJNI is OFF
12-16 09:24:23.606: DEBUG/dalvikvm(8951): creating instr width table
12-16 09:24:23.656: DEBUG/AndroidRuntime(8951): --- registering native functions ---
12-16 09:24:23.916: DEBUG/AndroidRuntime(8951): Shutting down VM
12-16 09:24:23.916: DEBUG/dalvikvm(8951): Debugger has detached; object registry had 1 entries
12-16 09:24:23.916: INFO/AndroidRuntime(8951): NOTE: attach of thread 'Binder Thread #3' failed
12-16 09:24:24.076: DEBUG/AndroidRuntime(8960): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
12-16 09:24:24.076: DEBUG/AndroidRuntime(8960): CheckJNI is OFF
12-16 09:24:24.076: DEBUG/dalvikvm(8960): creating instr width table
12-16 09:24:24.126: DEBUG/AndroidRuntime(8960): --- registering native functions ---
12-16 09:24:24.376: INFO/ActivityManager(78): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=org.customview.harold/.ShowNumber }
12-16 09:24:24.426: DEBUG/AndroidRuntime(8960): Shutting down VM
12-16 09:24:24.426: DEBUG/jdwp(8960): Got wake-up signal, bailing out of select
12-16 09:24:24.426: DEBUG/dalvikvm(8960): Debugger has detached; object registry had 1 entries
12-16 09:24:24.456: INFO/AndroidRuntime(8960): NOTE: attach of thread 'Binder Thread #3' failed
12-16 09:24:24.456: VERBOSE/ViewNumber(8923): Number of Child: 1
12-16 09:24:24.496: VERBOSE/RenderScript_jni(164): surfaceDestroyed
12-16 09:24:24.526: INFO/ActivityManager(78): Displayed activity org.customview.harold/.ShowNumber: 104 ms (total 104 ms)
12-16 09:24:24.576: DEBUG/dalvikvm(158): GC_FOR_MALLOC freed 10631 objects / 526248 bytes in 52ms
12-16 09:24:34.606: DEBUG/dalvikvm(164): GC_EXPLICIT freed 1776 objects / 106960 bytes in 91ms

UPDATE 2

The Content is finally showing correctly up. The missing thing was to override the Method onLayout (thanks to Franco) in the RelativeLayout-Sublcass:

public class ViewNumber extends RelativeLayout {
...

    @Override
            protected void onLayout(boolean changed, int l, int t, int r, int b) {
                // TODO Auto-generated method stub
                for(int i = 0 ; i < getChildCount() ; i++){
                    getChildAt(i).layout(l, t, r, b);
                }
            }
...
}

Note: Later you should also override the Method onMeasurement(), but currently the content is also showing correctly without overriding it.

Now the solution for the Method initView from Franco do not align the TextView in the Center, but puts it in the top left corner. The solution from Konstantin puts it correctly in the Center of the View:

public class ViewNumber extends RelativeLayout {
...
private void initView(Context context){
        View.inflate(context, R.layout.shownumberlayout,this); 
    }
...
}

解决方案

Did you try this?

private void initView(Context context){
        inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.addView(inflater.inflate(R.layout.shownumberlayout, null));  
    }

EDIT: I respond quickly... a ViewGroup has the responsibility to prepare the layout for their children, in the layout method try this:

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            // TODO Auto-generated method stub
            for(int i = 0 ; i < getChildCount() ; i++){
                getChildAt(i).layout(l, t, r, b);
            }
        }