سؤال

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;
}

نصائح أخرى

1) NullPointerExcption occus when you try to asscess a View which does not resides in your layout file (activity_manage_seeds).

Please make sure that your Viewgroup layout_manage is there in activity_manage_seeds.xml file.

2) Regarding your seekbar position you need to add layout parameters to set its proper location, provided you viewGroup R.id.container resides in activity_manage_seeds.xml which is not there in your xml file shown above.

You got the linear layout id wrong in the code try changing it to layout_manage instead of container.

You are trying to get a View that is not on your xml thats why it returns nullpointer..

change the layout of this :

setContentView(R.layout.activity_manage_seeds);

to the layout where the id R.id.container resides

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top