在活动的使用findViewById的onCreate行为不预期 [英] Using findViewById in Activity's onCreate not behaving as expected

查看:309
本文介绍了在活动的使用findViewById的onCreate行为不预期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用'RangeSeekBar(的https:/ /$c$c.google.com/p/range-seek-bar/ <​​/A>)。这已在code,而不是XML来完成,所以我插入的样本code到我的活动的onCreate方法的指导。

我的code。在下面列出的 findViewById 方法分崩离析。使用示例code,我得到以下两个结果:


  1. 如果我尝试直接参照其ID获得的LinearLayout,我得到一个空指针异常。我期望这将提供的LinearLayout,我不明白这是为什么空。


  2. 如果我指的是 R.id.container ,我可以插入RangeSeekBar但重叠的第一个字段。需要注意的是,如果我尝试到容器转换为的LinearLayout,而不是ViewGroup中,我得到的指示容器是的FrameLayout,还告诉我,容器不是的LinearLayout,我想这是一个错误。


我的问题是,如何插入RangeSeekBar成片段的ViewGroup,使其坚持的LinearLayout?如何我找回我的片段的LinearLayout从活动的onCreate和避免空指针异常?

更新:我有previously列出的XML片段,而不是活动的XML。我已经与以下两个XML更新的问题。

下面是我的onCreate方法:

 保护无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_manage_seeds);    如果(savedInstanceState == NULL){
        。getSupportFragmentManager()调用BeginTransaction()加(R.id.container,新PlaceholderFragment())提交()。
    }    //我更换了样品code的背景与getBaseContext()这应该是别的东西?
    // RangeSeekBar&LT;整数GT;搜索栏=新RangeSeekBar&LT;整数GT;(20,75,背景); // code样品
    RangeSeekBar&LT;整数GT;搜索栏=新RangeSeekBar&所述;整数&GT;(0,40,getBaseContext()); //我的版本    seekBar.setOnRangeSeekBarChangeListener(新OnRangeSeekBarChangeListener&LT;整数GT;(){
        @覆盖
        公共无效onRangeSeekBarValues​​Changed(RangeSeekBar&LT;&GT;酒吧,整数minValue(最小值),整数maxValue(最大值)){
            //处理更改范围值
            Log.i(TAG,用户选择新的范围值:MIN =+ minValue(最小值)+,MAX =+包括maxValue);
        }
    });    //添加RangeSeekBar至pre定义布局
    // ViewGroup中布局=(ViewGroup中)findViewById(小于你的布局-ID&GT;); //样品code
    ViewGroup中布局=(ViewGroup中)findViewById(R.id.container); //我的code作品那种
    layout.addView(搜索栏); //这个插入RangeSeekBar重叠名称字段    // ViewGroup中布局=(ViewGroup中)findViewById(R.id.layout_manage); //我的code,它返回一个空指针异常运行时
    //layout.addView(seekBar); //这将导致空指针异常,因为上面的行返回null。
}

下面是我的XML片段:

 &LT; LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s
    机器人:ID =@ + ID / layout_manage
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:方向=垂直&GT;    &LT; EditText上机器人:ID =@ + ID / test_edit_name
        机器人:layout_width =match_parent
        机器人:layout_height =WRAP_CONTENT
        机器人:提示=@字符串/ test_edit_name/&GT;    &LT; EditText上机器人:ID =@ + ID / test_edit_type
        机器人:layout_width =match_parent
        机器人:layout_height =WRAP_CONTENT
        机器人:提示=@字符串/ test_edit_type/&GT;    &LT;! - 我想RangeSeekBar这里添加自定义。必须通过Java code,不可能通过XML来完成 - &GT;    &LT;按钮
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:文字=@字符串/ test_button_save
        机器人:layout_gravity =右/&GT;
&LT; / LinearLayout中&GT;

下面是我的activity_manage_seeds XML:

 &LT;的FrameLayout的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s
    机器人:ID =@ + ID /容器
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    工具:上下文=com.mypackage.myapp.ManageSeedsActivity
    工具:忽略=MergeRootFrame/&GT;


我觉得一个整洁的解决方案,这是一个的FrameLayout添加到您现有的LinearLayout,并添加RangeSeekBar到的FrameLayout。见下图:

 &LT;! - 活动布局 - &GT;
&LT; LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
          的xmlns:工具=htt​​p://schemas.android.com/tool​​s
          机器人:ID =@ + ID / layout_manage
          机器人:layout_width =match_parent
          机器人:layout_height =match_parent
          机器人:方向=垂直&GT;&LT; EditText上机器人:ID =@ + ID / test_edit_name
          机器人:layout_width =match_parent
          机器人:layout_height =WRAP_CONTENT/&GT;&LT; EditText上机器人:ID =@ + ID / test_edit_type
          机器人:layout_width =match_parent
          机器人:layout_height =WRAP_CONTENT/&GT;&所述;! - 这是RangeSeekBar容器 - &GT;
&LT;的FrameLayout
    机器人:ID =@ + ID / range_seek_bar_container
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT/&GT;&LT;按钮
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_gravity =右/&GT;
&LT; / LinearLayout中&GT;

您onCreate()方法可能如下所示:

  @覆盖
保护无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);    RangeSeekBar rangeSeekBar =新RangeSeekBar&LT;整数GT;(20,75,背景);    ViewGroup中rangeBarContainer =(ViewGroup中)findViewById(R.id.range_seek_bar_container);
    rangeBarContainer.addView(rangeSeekBar);
}

这使得它更容易编辑RangeSeekBar的布局属性。

更新

在阅读新的code,我注意到你正试图从你的活动 code编辑片段中的一个布局。你不应该这样做。里面的工作 PlaceholderFragment

您onCreateView()内 PlaceholderFragment 方法:

  @覆盖
公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,
        捆绑savedInstanceState){
    查看rootView = inflater.inflate(R.layout.your_fragment_layout,集装箱,FALSE);    RangeSeekBar rangeSeekBar =新RangeSeekBar&LT;整数GT;(20,75,背景);    ViewGroup中rangeBarContainer =(ViewGroup中)rootView.findViewById(R.id.range_seek_bar_container);
    rangeBarContainer.addView(rangeSeekBar);    返回rootView;
}

I'm attempting to use a 'RangeSeekBar' (https://code.google.com/p/range-seek-bar/). This has to be done in the code rather than the XML, so I've plugged the sample code into my activity's onCreate method as instructed.

My code falls apart at the findViewById method outlined below. Using the sample code, I get the following two outcomes:

  1. If I try to get the LinearLayout directly by referring to its ID, I get a null pointer exception. I expect this to provide the LinearLayout, I don't understand why this is null.

  2. If I refer to R.id.container, I can insert the RangeSeekBar but it overlaps the first field. Note that if I try to cast the container to a LinearLayout instead of ViewGroup, I get an error that indicates that the container is a FrameLayout, which tells me the container isn't the LinearLayout that I want it to be.

My question is this, How do I insert the RangeSeekBar into the fragment ViewGroup so that it adheres to the LinearLayout? Or, How do I retrieve my fragment LinearLayout from the activity onCreate and avoid a null pointer exception?

Update: I had previously listed the fragment xml rather than the activity xml. I've updated the question with both XML below.

Here's my onCreate method:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_manage_seeds);

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();
    }

    // I replaced the sample code's "context" with getBaseContext() should this be something else??
    //RangeSeekBar<Integer> seekBar = new RangeSeekBar<Integer>(20, 75, context); //CODE SAMPLE 
    RangeSeekBar<Integer> seekBar = new RangeSeekBar<Integer>(0, 40, getBaseContext()); //MY VERSION

    seekBar.setOnRangeSeekBarChangeListener(new OnRangeSeekBarChangeListener<Integer>() {
        @Override
        public void onRangeSeekBarValuesChanged(RangeSeekBar<?> bar, Integer minValue, Integer maxValue) {
            // handle changed range values
            Log.i(TAG, "User selected new range values: MIN=" + minValue + ", MAX=" + maxValue);
        }
    });

    // add RangeSeekBar to pre-defined layout
    //ViewGroup layout = (ViewGroup) findViewById(<your-layout-id>); //SAMPLE CODE
    ViewGroup layout = (ViewGroup) findViewById(R.id.container); //MY CODE THAT SORT OF WORKS
    layout.addView(seekBar); // This inserts the RangeSeekBar overlapping the Name field

    //ViewGroup layout = (ViewGroup) findViewById(R.id.layout_manage); //MY CODE THAT RETURNS A NULL POINTER EXCEPTION AT RUNTIME
    //layout.addView(seekBar); // This causes the null pointer exception because the line above returns null.
}

Here's my fragment XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout_manage"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <EditText android:id="@+id/test_edit_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/test_edit_name" />

    <EditText android:id="@+id/test_edit_type"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/test_edit_type" />

    <!-- I want the custom RangeSeekBar added here. Must be done via java code, not possible through XML -->

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/test_button_save"
        android:layout_gravity="right" />
</LinearLayout>

Here's my activity_manage_seeds xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.mypackage.myapp.ManageSeedsActivity"
    tools:ignore="MergeRootFrame" />

解决方案

I think a tidier solution to this is to add a FrameLayout into your existing LinearLayout, and add the RangeSeekBar into the FrameLayout. See below:

<!-- Activity Layout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:id="@+id/layout_manage"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical" >

<EditText android:id="@+id/test_edit_name"
          android:layout_width="match_parent"
          android:layout_height="wrap_content" />

<EditText android:id="@+id/test_edit_type"
          android:layout_width="match_parent"
          android:layout_height="wrap_content" />

<!-- This is the container for the RangeSeekBar -->
<FrameLayout
    android:id="@+id/range_seek_bar_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="right" />
</LinearLayout>

Your onCreate() method may look as follows:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RangeSeekBar rangeSeekBar = new RangeSeekBar<Integer>(20, 75, context);

    ViewGroup rangeBarContainer = (ViewGroup) findViewById(R.id.range_seek_bar_container);
    rangeBarContainer.addView(rangeSeekBar);
}

This makes it much easier to edit the RangeSeekBar's layout attributes

Update

Upon reading your new code, I noticed you are attempting to edit the layout of one of your Fragments from your Activity code. You shouldn't do this. Work inside PlaceholderFragment.

Your onCreateView() method inside PlaceholderFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.your_fragment_layout, container, false);

    RangeSeekBar rangeSeekBar = new RangeSeekBar<Integer>(20, 75, context);

    ViewGroup rangeBarContainer = (ViewGroup) rootView.findViewById(R.id.range_seek_bar_container);
    rangeBarContainer.addView(rangeSeekBar);

    return rootView;
}

这篇关于在活动的使用findViewById的onCreate行为不预期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆