简体   繁体   中英

“java.lang.NullPointerException” error when try to initialize a ListView (or its adapter)

I created this listView in a separate project and everything works fine there. When I tried to bring it to the main App I'm developing I faced this error (among others):

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
        at com.example.tiago.newapponthego.MainActivity.initialVocabList(MainActivity.java:148)
        at com.example.tiago.newapponthego.MainActivity.onCreate(MainActivity.java:110)

it's pointing to this line:

vocabListView.setAdapter(itemsAdapter);

This is my MainActivity:

public class MainActivity extends ActionBarActivity

    implements NavigationDrawerFragment.NavigationDrawerCallbacks {

//initialize timer
private TextView timerTextView;
//from tutorial
private long startTime = 0L;
private Handler customHandler = new Handler();
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;

//initialize points
private TextView pointsTextView;
private boolean initialBonus = true;
private int totalPoints = 0;

//initialize vocab list
private ArrayList<String> vocabsList;
private ArrayAdapter<String> itemsAdapter;
private ListView vocabListView;
private String clickedVocab;


static Random randomBackground = new Random();

/**
 * Fragment managing the behaviors, interactions and presentation of the navigation drawer.
 */
private NavigationDrawerFragment mNavigationDrawerFragment;

/**
 * Used to store the last screen title. For use in {@link #restoreActionBar()}.
 */
private CharSequence mTitle;

public static int randomRgb(int min, int max) {

    //Random randomBackground = new Random();  //already done in the main scope

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int rgbReturn = randomBackground.nextInt((max - min) + 1) + min;

    return rgbReturn;
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
}

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main); // this is the original one

    //Retrieve values for Timer and points
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    timeInMilliseconds = preferences.getLong("Time", 0);
    totalPoints = preferences.getInt("Points", 0);


    //starts timer and
    timerTextView = (TextView) findViewById(R.id.timeTV);
    startTime = SystemClock.uptimeMillis();
    customHandler.postDelayed(updateTimerThread, 0);
    timeSwapBuff += timeInMilliseconds;
    //points

    initialPoints();

    //constructor vocabulary list
    initialVocabList();    //  <---- THE PROBLEM IS TRIGGERED HERE

    //native initialization
    mNavigationDrawerFragment = (NavigationDrawerFragment)
            getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
    mTitle = getTitle();

    // Set up the drawer.
    mNavigationDrawerFragment.setUp(
            R.id.navigation_drawer,
            (DrawerLayout) findViewById(R.id.drawer_layout));

}

public void initialVocabList() {

    // ADD HERE
    vocabListView = (ListView) findViewById(R.id.vocabList);
    //vocabsList = new ArrayList<String>();
    //retrieve from SharedPreferences
    TinyDB tinydb = new TinyDB(getBaseContext());
    vocabsList = tinydb.getListString("vocabs");
    //itemsAdapter = new ArrayAdapter<String>(this, R.layout.vocab_notes_item, items);
    itemsAdapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.vocab_notes_item, vocabsList);

    vocabListView.setAdapter(itemsAdapter);    //    <---- HERE IS THE PROBLEM

    // Setup remove listener method call
    setupListViewListener();
    // Setup Onclick method call
    setOnClickListener();
}

private void setupListViewListener() {
    vocabListView.setOnItemLongClickListener(
            new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> adapter,
                                               View item, int pos, long id) {
                    // Remove the item within array at position
                    /* createDelVocDialog();
                   if (confirmDelete){          //if boolean is true
                        items.remove(pos);
                    }*/
                    noteDeletedToast(vocabsList.get(pos));
                    vocabsList.remove(pos);

                    // Refresh the adapter
                    itemsAdapter.notifyDataSetChanged();
                    // Return true consumes the long click event (marks it handled)
                    return true;
                }

            });

}

private void setOnClickListener() {
    vocabListView.setOnItemClickListener(
            new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapter,
                                        View view, int pos, long id) {
                    //System.out.println("entrei");   //anderson's test "dividir para conquistar"
                    Context context = view.getContext();
                    clickedVocab = vocabsList.get(pos);
                    Toast.makeText(context, "Item: " + clickedVocab, Toast.LENGTH_SHORT).show();
                }
            });
}

private void noteDeletedToast(String note) {
    Toast.makeText(this, "Vocab note deleted: " + note, Toast.LENGTH_SHORT).show();
}

;

public void onAddVocab(View v) {
    EditText vocabTextBox = (EditText) findViewById(R.id.edTextVocab);


    if (vocabTextBox.getText().toString().equals("")) {         //Check if the EditText is not empty
        Toast.makeText(this, "You forgot to write in the box!", Toast.LENGTH_SHORT).show();
        return;

    } else {
        String itemText = vocabTextBox.getText().toString();
        itemsAdapter.add(itemText.trim());  //This also performs "trim" on text
        vocabTextBox.setText("");
        Toast.makeText(this, "Note added", Toast.LENGTH_SHORT).show();

        //save to SharedPreferences
        TinyDB tinydb = new TinyDB(getBaseContext());
        tinydb.putListString("vocabs", vocabsList);


        hideKeyboard();
    }
}

private void hideKeyboard() {
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

public void initialPoints() {
    pointsTextView = (TextView) findViewById(R.id.pointsTV);
    pointsTextView.setText(String.valueOf(totalPoints));
}

@Override //native
public void onNavigationDrawerItemSelected(int position) {

    Fragment objFragment = null;

    switch (position) {
        case 0:
            objFragment = new home_fragment();
            //findViewById(com.example.tiago.newapponthego.R.id.mainContainer).setBackgroundColor(Color.rgb(255, 255, 255));

            break;
        case 1:
            objFragment = new proverbs_fragment();
            findViewById(com.example.tiago.newapponthego.R.id.mainContainer).setBackgroundColor(Color.rgb(255, 255, 255));

            break;
        case 2:
            objFragment = new jokes_fragment();
            findViewById(com.example.tiago.newapponthego.R.id.mainContainer).setBackgroundColor(Color.rgb(255, 255, 255));

            break;
        case 3:
            objFragment = new VocabularyFragment();
            //findViewById(com.example.tiago.newapponthego.R.id.mainContainer).setBackgroundColor(Color.rgb(255, 255, 255));

            break;
    }

    // update the main content by replacing fragments
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction()
            .replace(R.id.mainContainer, objFragment)
            .commit();
}

public void onSectionAttached(int number) {
    switch (number) {
        case 1:
            mTitle = getString(R.string.nav1home);
            break;
        case 2:
            mTitle = getString(R.string.nav2prov);
            break;
        case 3:
            mTitle = getString(R.string.nav3joke);
            break;
    }
}

public void restoreActionBar() {
    ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayShowTitleEnabled(true);
    actionBar.setTitle(mTitle);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if (!mNavigationDrawerFragment.isDrawerOpen()) {
        // Only show items in the action bar relevant to this screen
        // if the drawer is not showing. Otherwise, let the drawer
        // decide what to show in the action bar.
        getMenuInflater().inflate(R.menu.main_activity_navigation, menu);
        restoreActionBar();
        return true;
    }
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}


public void randomJoke(View y) {
    //String chosenJoke = new String();
    randomBground();

    Button button = (Button) y;
    MyArrayLists.pickJoke();
    String chosenJoke = MyArrayLists.jokeTxt.toString();
    TextView theTextView = (TextView) findViewById(R.id.thisTextView);
    theTextView.setText(chosenJoke);
    addPoints(1);
    // theTextView.setOnClickListener();
}

public void randomProv(View y) {
    randomBground();
    Button button = (Button) y;
    MyArrayLists.pickProv();
    String chosenProv = MyArrayLists.provTxt.toString();
    TextView theTextView = (TextView) findViewById(R.id.thisTextView);
    theTextView.setText(chosenProv);
    addPoints(1);
}

public void randomBground() {
    Integer R = randomRgb(225, 250);
    Integer G = randomRgb(225, 250);
    Integer B = randomRgb(225, 250);
    findViewById(com.example.tiago.newapponthego.R.id.mainContainer).setBackgroundColor(Color.rgb(R, G, B));
}

public void whiteBackground() {
    findViewById(com.example.tiago.newapponthego.R.id.mainContainer).setBackgroundColor(Color.rgb(255, 255, 255));

}

public void saveTime() {
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    SharedPreferences.Editor editor = preferences.edit();
    editor.putLong("Time", timeInMilliseconds);
    editor.apply();
}

public void savePoints() {
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    SharedPreferences.Editor editor = preferences.edit();
    editor.putInt("Points", totalPoints);
    editor.apply();
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {
    /**
     * The fragment argument representing the section number for this
     * fragment.
     */
    private static final String ARG_SECTION_NUMBER = "section_number";

    public PlaceholderFragment() {
    }

    /**
     * Returns a new instance of this fragment for the given section
     * number.
     */
    public static PlaceholderFragment newInstance(int sectionNumber) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

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


    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        ((MainActivity) activity).onSectionAttached(
                getArguments().getInt(ARG_SECTION_NUMBER));
    }
}

public void addPoints(int pointsToAdd) {
    totalPoints = totalPoints + pointsToAdd;
    // run the mUpdateUITimerTask's run() method in 1000 milliseconds from now
    mHandler.postDelayed(mUpdateUITimerTask, 100);
    savePoints();
}

private final Runnable mUpdateUITimerTask = new Runnable() {
    public void run() {
        // do whatever you want to change here, like:
        pointsTextView.setText(String.valueOf(totalPoints));
    }
};

private final Handler mHandler = new Handler();

private Runnable updateTimerThread = new Runnable() {

    public void run() {

        timeInMilliseconds = SystemClock.uptimeMillis() - startTime;

        updatedTime = timeSwapBuff + timeInMilliseconds;

        int secs = (int) (updatedTime / 1000);
        int mins = secs / 60;
        //int upTime = (int) updatedTime;

        if (secs == 120 && initialBonus == true) {
            addPoints(10);
            initialBonus = false;
        }

        secs = secs % 60;


        //int milliseconds = (int) (updatedTime % 1000); // Show milliseconds
        timerTextView.setText("" + mins + ":"
                        + String.format("%02d", secs)
                // + ":" + String.format("%03d", milliseconds) // Show milliseconds
        );
        customHandler.postDelayed(this, 0);
        saveTime();
    }
};

Possibly relevant fragment:

public class VocabularyFragment extends Fragment {

View rootview;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    rootview = inflater.inflate(R.layout.fragment_vocab_list,container, false);

    return rootview;
}

This fragment layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/console_height"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".ListViewActivity">

<LinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/linearLayout"
    android:weightSum="1">

    <EditText
        android:layout_width="258dp"
        android:layout_height="wrap_content"
        android:id="@+id/edTextVocab"
        android:layout_weight="0.98"
        android:paddingRight="5dp"
        android:paddingTop="5dp"
        android:singleLine="true"
        android:hint="Write a note here" />

    <Button
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:id="@+id/BtnAddVocab"
        android:onClick="onAddVocab"
        android:background="@mipmap/ic_add" />
</LinearLayout>

<include
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    layout="@layout/vocab_notes_list"
    android:layout_centerHorizontal="true"
    android:layout_below="@+id/linearLayout"
    android:id="@+id/include"
    android:layout_above="@+id/textView" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="Tap and hold to delete"
    android:id="@+id/textView"
    android:layout_centerHorizontal="true"
    android:layout_alignParentBottom="true"
    android:textColor="#ffb3b3b3"
    android:textSize="@dimen/abc_text_size_medium_material" />

The main layout:

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">


<FrameLayout android:id="@+id/mainContainer"     android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffffff">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:id="@+id/backgroundMain"
        android:layout_height="wrap_content"
        android:layout_gravity="start"
        android:layout_marginTop="2dp"
        android:layout_marginBottom="2dp"
        android:background="#ffe6e2e6"
        android:gravity="center_vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="0"
            android:id="@+id/pointsTV"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="10dp"
            android:layout_marginStart="10dp"
            android:layout_marginRight="8dp"
            android:layout_marginEnd="8dp"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="points"
            android:id="@+id/points"
            android:layout_gravity="center_vertical"
            android:layout_marginRight="10dp"
            android:layout_marginEnd="10dp"/>
        <!-- timer icon-->
        <ImageView
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:id="@+id/imageView"
            android:src="@mipmap/ic_timer_gr"
            android:layout_gravity="center_vertical"
            android:contentDescription="timerIcon" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
            android:text="@string/timerVal"
            android:id="@+id/timeTV"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:visibility="visible"
            android:textColor="@android:color/background_dark" />
    </LinearLayout>

</FrameLayout>

<!-- android:layout_gravity="start" tells DrawerLayout to treat
     this as a sliding drawer on the left side for left-to-right
     languages and on the right side for right-to-left languages.
     If you're not building against API 17 or higher, use
     android:layout_gravity="left" instead. -->

<fragment android:id="@+id/navigation_drawer"
    android:layout_width="@dimen/navigation_drawer_width"     
    android:layout_height="match_parent" 
    android:layout_gravity="start"
    android:name="com.example.tiago.newapponthego.NavigationDrawerFragment"
    tools:layout="@layout/fragment_navigation_drawer" />

There are more java files and layouts, I can add them in a second if requested.

Thanks in advance

EDIT: Here is the missing xml file: vocab_notes_list

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rlLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${packageName}.${activityClass}" >

<ListView
    android:id="@+id/vocabList"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentTop="true" >

</ListView>

</RelativeLayout>
vocabListView = (ListView) findViewById(R.id.vocabList);

After this, vocabListView is still null. So therefore findViewById() is returning null, so that view is not found.

The view you're trying to get need to have this property:

android:id="@+id/vocabList"

Simply from your code I found, you don't have any listView vocabList , in activity_main layout file.

vocabListView = (ListView) findViewById(R.id.vocabList);

so this line give you null vocabListView in MainActivity .

And if this part of fragment_vocab_list layout file,

your code goes..

public class VocabularyFragment extends Fragment {

View rootview;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    rootview = inflater.inflate(R.layout.fragment_vocab_list,container, false);
    initialVocabList(rootview);
    return rootview;
 }
}

And function should be,

public void initialVocabList(View view) {

    // ADD HERE
    vocabListView = (ListView)view.findViewById(R.id.vocabList);
    //vocabsList = new ArrayList<String>();
    //retrieve from SharedPreferences
    TinyDB tinydb = new TinyDB(getBaseContext());
    vocabsList = tinydb.getListString("vocabs");
    //itemsAdapter = new ArrayAdapter<String>(this, R.layout.vocab_notes_item, items);
    itemsAdapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.vocab_notes_item, vocabsList);

    vocabListView.setAdapter(itemsAdapter);    

    // Setup remove listener method call
    setupListViewListener();
    // Setup Onclick method call
    setOnClickListener();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM