0

I am a beginner in Java and Android Studio and I am trying to build an app by following online tutorials. Everything good up to the point that I arrived to tabbed Activity. My app will have One main activity and tree tabs associated "FIRST WORDS"(that will have only some text describing the app), "WORDS"(that will have a grid view) and "GAMES"(that will also have a grid view inside). Both GridViews will lead to other activities on item click. Managed to do everything up to the point where I have to introduce the GridView in the second tab. I write it in the xml I write the code in .MainActivity.java, there is no error on the code, but when I try to run the app it crashes with

"Unable to start activity ComponentInfo{com.gadgetcatch.firstwords/com.gadgetcatch.firstwords.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.GridView.setAdapter(android.widget.ListAdapter)' on a null object reference"

Here is the words.xml

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/rsz_1rsz_words">


    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/action_words"
        android:gravity="center"
        android:textSize="@dimen/abc_text_size_large_material"
        android:layout_marginTop="70dp"
        android:layout_marginLeft="70dp"
        android:layout_marginRight="70dp"
        android:id="@+id/words_textview"/>


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/words_textview"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="60dp"
        android:layout_marginStart="50dp"
        android:layout_marginLeft="50dp"
        android:layout_marginEnd="50dp"
        android:layout_marginRight="50dp">

        <GridView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/gridview"
            android:numColumns="auto_fit"
            android:verticalSpacing="80dp"
            android:horizontalSpacing="40dp"
            android:columnWidth="100dp"
            android:stretchMode="columnWidth"
            android:gravity="center" />


    </LinearLayout>

</RelativeLayout>

Here is the main activity java code

package com.gadgetcatch.firstwords;

import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

import java.util.Locale;

public class MainActivity extends AppCompatActivity {

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

        GridView gridview = (GridView) findViewById(R.id.gridview);
        gridview.setAdapter(new ImageAdapter(this));

        gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v,
                                    int position, long id) {
                Toast.makeText(MainActivity.this, "" + position,
                        Toast.LENGTH_SHORT).show();
            }
        });

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        /*
      The {@link android.support.v4.view.PagerAdapter} that will provide
      fragments for each of the sections. We use a
      {@link FragmentPagerAdapter} derivative, which will keep every
      loaded fragment in memory. If this becomes too memory intensive, it
      may be best to switch to a
      {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
        SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        /*
      The {@link ViewPager} that will host the section contents.
     */
        ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        //Add a tab bar navigation
        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabbar);
        tabLayout.setupWithViewPager(mViewPager);

        android.support.v7.app.ActionBar actionBar = getSupportActionBar();
        assert actionBar != null;
        actionBar.setDisplayShowHomeEnabled(true);
        actionBar.setIcon(R.mipmap.ic_launcher);


    }

    public class ImageAdapter extends BaseAdapter {
        private Context mContext;

        public ImageAdapter(Context c){
            mContext = c;
        }

        public int getCount(){
            return imageIDs.length;
        }

        public Object getItem(int position){
            return null;
        }

        public long getItemId(int position){
            return 0;
        }

        private Integer[] imageIDs = {
                R.drawable.animals_png, R.drawable.food_png, R.drawable.clothing_png,
                R.drawable.colors_png, R.drawable.body_png, R.drawable.transport_png
        };

        public View getView(int position, View convertView, ViewGroup parent){
            ImageView imageView;
            if (convertView == null){
                imageView = new ImageView(mContext);
                imageView.setLayoutParams(new GridView.LayoutParams(85,85));
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageView.setPadding(8,8,8,8);
            }
            else {
                imageView = (ImageView) convertView;
            }
            imageView.setImageResource(imageIDs[position]);
            return imageView;
        }

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

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




    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment (defined as a static inner class below).
            switch (position) {
                case 0:
                    return PlaceholderFragment.newInstance(position + 1);
                case 1:
                    return Words.newInstance(position + 1);
                case 2:
                    return Games.newInstance(position + 1);
            }
            return null;

        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {
                case 0:
                    return getString(R.string.title_section1).toUpperCase(l);
                case 1:
                    return getString(R.string.title_section2).toUpperCase(l);
                case 2:
                    return getString(R.string.title_section3).toUpperCase(l);
            }
            return null;
        }
    }
}

Please explain what am I doing wrong. I have attached also an app screen below that maybe might help you to make an idea of hat I am trying to do. Thanks in advance for your support.

Sreen with the App

Here is also what I have in the Words.java:

    public class Words extends Fragment {

    private static final String ARG_SECTION_NUMBER = "section_number";

    public static Words newInstance(int sectionNumber) {
        Words fragment = new Words();
        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 v =inflater.inflate(R.layout.words,container,false);
        return v;


    }

}

Here is what I have now in Words.java after I add here the code for the GridView:

 public class Words extends Fragment {

    GridView gridview;
    private static final String ARG_SECTION_NUMBER = "section_number";

    public static Words newInstance(int sectionNumber) {
        Words fragment = new Words();
        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 v =inflater.inflate(R.layout.words,container,false);
        GridView gridview = (GridView)v.findViewById(R.id.gridview);
        gridview.setAdapter(new ImageAdapter(this));
        gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v,
                                    int position, long id) {
                Toast.makeText(MainActivity.this, "" + position,
                        Toast.LENGTH_SHORT).show();
            }
        });

        return v;


    }

    public class ImageAdapter extends BaseAdapter {
        private Context mContext;

        public ImageAdapter(Context c){
            mContext = c;
        }

        public int getCount(){
            return imageIDs.length;
        }

        public Object getItem(int position){
            return null;
        }

        public long getItemId(int position){
            return 0;
        }

        private Integer[] imageIDs = {
                R.drawable.animals_png, R.drawable.food_png, R.drawable.clothing_png,
                R.drawable.colors_png, R.drawable.body_png, R.drawable.transport_png
        };

        public View getView(int position, View convertView, ViewGroup parent){
            ImageView imageView;
            if (convertView == null){
                imageView = new ImageView(mContext);
                imageView.setLayoutParams(new GridView.LayoutParams(85,85));
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageView.setPadding(8,8,8,8);
            }
            else {
                imageView = (ImageView) convertView;
            }
            imageView.setImageResource(imageIDs[position]);
            return imageView;
        }

    }
}

The errors that appear now are in the onCreateView giving me an error on gridview.setAdapter(new ImageAdapter(this)); (the error is for "this" saying that Image Adapter (android.content.Context) cannot be applied to com.gadgetcatch.firstwords.Words)

And te second error is for the Toast message saying that cannot resolve method makeText(com.gadgetcatch.firstwords.Words, java.lang.String, int)

Alex Simion
  • 93
  • 1
  • 14
  • 1
    As mention in Question `GridView` is in `words.xml` but currently `activity_main.xml` layout is used in `setContentView ` – ρяσѕρєя K Jan 22 '16 at 11:44
  • OK, So in this case, as I cannot change the activity_main.xml I would have to add this code in the Words.java , no? As that would be the corresponding java class for words.xml. I thought about that but when I add the code there it gives me a lot of errors... – Alex Simion Jan 22 '16 at 13:02
  • Is there nobody that can explain what I'm doing wrong? – Alex Simion Jan 23 '16 at 18:48

0 Answers0