Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

Mike Papamichail
Mike Papamichail
4,883 Points

Image Adapter not able to initialize image Views

Hello there,

UPDATE: Check out my repo for easier code editing and viewing comfort : Github Repo

I am developing an app in which, when the app starts the mainActivity.java class adds in the mainScreenFragment.java fragment which contains a gridView layout with imageViews initialized by my ImageAdapter.java class.

What i want to achieve here is this: When the app starts, the mainScreenFragment is automatically loaded into the mainActivity class and then when the user clicks on the 1st item inside the context menu(created after long pressing on an imageView in the mainScreenFragment) i am trying to pass an Integer value( which is retrieved from my ImageAdapter.java class) to my UserBoxGLBFragment.java class (this fragment is accessed when the user clicks on the 2nd menu item from my drawer Layout)in order to use it as an ImageResource for my UserBoxGLBImageAdapter.java class. However, it doesn't work :(

Now, as you can see in my code i am using a method called

private void addSelectedCardToGlobalUserBox(int position) {
...
}

in order to get that Integer and pass it into my UserBoxGLBFragment.java class which with the following method, passes the Integer to the UserBoxGLBImageAdapter.java class :

    public void addInteger(Integer integer) {
        adapter.addDrawableToList(integer);
    }

Inside my UserBoxGLBImageAdapter.java class i am trying to update my grid's imageView with a new ImageResource using the Integer which is now saved in the mGlobalIcons List.

SADLY, the imageView updating part does not work and i cannot understand why. I am hoping that someone here can help me , this issue has been bothering me for 3 weeks and it's holding my app's release back. Please help me figure this out.

Here are my classes:

MainActivity.java
public class MainActivity extends AppCompatActivity {

    private Toolbar mToolbar;

    // NavMenu member vars
    private DrawerLayout mDrawerLayout;
    private NavigationView navigationView;
    private ActionBarDrawerToggle mToggle; // Button for toggling the side menu

    // Keeps the position of the previously selected menu item(0 : Home)
    int position = 0;

    // Declaring our dialog
    ImportantDialogFragment dialogFragment = new ImportantDialogFragment();

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

        // Showing the disclaimer dialog every time the app starts
        dialogFragment.show(getSupportFragmentManager(),"IMPORTANT_NOTICE");

        mDrawerLayout = findViewById(R.id.drawerLayout);
        navigationView = findViewById(R.id.nav_view);
        mToggle = new ActionBarDrawerToggle(this,mDrawerLayout,R.string.drawer_open,R.string.drawer_closed); // Instantiating our button


        mToolbar = findViewById(R.id.navActionBar);
        setSupportActionBar(mToolbar); // check quick doq
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        mToolbar.setTitle("");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        // Sets the default selected menu item, to the Home item
        navigationView.getMenu().findItem(R.id.nav_home).setChecked(true);

        // Used to help on check and uncheck menu items when the user clicks on them
        final List<MenuItem> items = new ArrayList<>();
        Menu menu;
        menu = navigationView.getMenu();

        // Fill the list with all the menu items
        for(int i=0; i<menu.size();i++) {
            items.add(menu.getItem(i));
        }

       // Toast.makeText(this, "size:" + items.size(), Toast.LENGTH_SHORT).show();

        // Set the default starting screen to the mainScreen
        FragmentManager startingScreenManager = getSupportFragmentManager();
        FragmentTransaction startingScreenTransaction = startingScreenManager.beginTransaction();

        MainScreenFragment fragment = new MainScreenFragment();
        startingScreenTransaction.add(R.id.FrameLayoutContainer, fragment);
        startingScreenTransaction.commit();

        final UserBoxGLBFragment glbFragment = new UserBoxGLBFragment();
        // When an item inside the NavView gets clicked, then handle the event...
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {

            // Initializing these vars again for use in this inner class
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

            // Replace the main Fragment in this activity based on the menu item selected
                switch (item.getItemId()) {
                    case R.id.nav_home:
                        MainScreenFragment mainScreenFragment = new MainScreenFragment();
                        fragmentTransaction.replace(R.id.FrameLayoutContainer,mainScreenFragment);
                        fragmentTransaction.commit();
                        break;
                    case R.id.nav_UserBoxGLB:
                        //UserBoxGLBFragment glbFragment = new UserBoxGLBFragment();
                        fragmentTransaction.replace(R.id.FrameLayoutContainer,glbFragment);
                        fragmentTransaction.commit();
                        break;
                    case R.id.nav_UserBoxJP:
                        break;
                    case R.id.nav_events:
                        Toast.makeText(MainActivity.this, "Events are not available yet! Sorry", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.nav_feedback:
                        composeEmail(emails,"Feedback", "[Your message here]");
                        break;
                    case R.id.nav_contact_us:
                        composeEmail(emails,"Contact Us", "[Your message here]");
                        break;
                    case R.id.nav_website:
                        // Open the website's URL in a browser window
                        Intent intent = new Intent();
                        intent.setAction(Intent.ACTION_VIEW);
                        intent.addCategory(Intent.CATEGORY_BROWSABLE);
                        intent.setData(Uri.parse("http://www.google.com"));
                        startActivity(intent);
                        break;
                    case R.id.nav_about:
                        Intent aboutIntent = new Intent(MainActivity.this, AboutPageActivity.class);
                        startActivity(aboutIntent);
                        break;
                    default:
                        return onNavigationItemSelected(item);
                }
                items.get(position).setChecked(false);
                item.setChecked(true);
                mDrawerLayout.closeDrawers();
                return false;
            }
        });

        mDrawerLayout.addDrawerListener(mToggle);
        // Set the hamburger icon's color
        mToggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.NavActionBarTextColor));
        mToggle.syncState();
    }

    // When an item from the Action Bar gets tapped, then...
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return mToggle.onOptionsItemSelected(item) || onOptionsItemSelected(item);
    }

    private String[] emails = {"SPDesignsOfficial@outlook.com"};

    /**
     * Send an email to the @adress with a @subject
     * @param addresses The email adress(es) to send the email to
     * @param subject The email's subject
     */
    public void composeEmail(String[] addresses, String subject, String message) {
        Intent intent = new Intent(Intent.ACTION_SENDTO);
        intent.setData(Uri.parse("mailto:")); // only email apps should handle this
        intent.putExtra(Intent.EXTRA_EMAIL, addresses);
        intent.putExtra(Intent.EXTRA_SUBJECT, subject);
        intent.putExtra(Intent.EXTRA_TEXT,message);
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivity(intent);
        }
    }
}

ImageAdapter.java:

public class ImageAdapter extends BaseAdapter {
    Context mContext;

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

    @Override
    public int getCount() {
        return mThumbIds.length;
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    // create a new ImageView for each item referenced by the Adapter
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        // If it's not recycled, initialize some attributes
        if (convertView == null) {
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(225, 225));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }
        imageView.setImageResource(mThumbIds[position]);
        return imageView;
    }

    public Integer getmThumbIds(int index) {
        return mThumbIds[index];
    }

    // References to our images
    private Integer[] mThumbIds = {
            R.drawable.beyondthe_ferocious_flash_majin_vegeta_icon
//            R.mipmap.full_tilt_kamehameha_super_saiyan2_gohan_youth_icon,
//            R.mipmap.merciless_condemnation_goku_black_super_saiyan_rose_and_zamasu_icon,
//            R.mipmap.everlasting_legend_super_saiyan_goku_icon,
//            R.mipmap.indestructible_saiyan_evil_legendary_super_saiyan_broly_icon
    };
}

MainScreenFragment.java:

public class MainScreenFragment extends Fragment {

    // Main Grid View
    GridView gridView;

    public MainScreenFragment() {
        // Required empty public constructor
    }

    // Create a Context Menu when an item in the GridView is long-pressed
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.setHeaderTitle("Card Options");
        //AdapterView.AdapterContextMenuInfo cmi = (AdapterView.AdapterContextMenuInfo) menuInfo;
        menu.add(1,v.getId(),0, "Add Card to GLB");
        menu.add(2,v.getId(),0,"Add Card to JP");
    }

    // When an item in the context menu gets selected, call a method
    @Override
    public boolean onContextItemSelected(MenuItem item) {

        // Get some extra info about the contextMenu
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

        int position = info.position; // clicked view's position

        if(item.getTitle().equals("Add Card to GLB")) {
            addCardMessage(position, "added to GLB");
            addSelectedCardToGlobalUserBox(position);
        } else if (item.getTitle().equals("Add Card to JP")) {
            addCardMessage(position , "added to JP");
        } else
        {
            return false;
        }
        return false;
    }

    /**
     * Creates a snackbar message, telling the user which card was added to which box
     * @param id The position of the chosen card
     * @param text Defines into which User Box the card was added
     */
    private void addCardMessage(int id, String text) {
          final Snackbar snackbar = Snackbar.make(gridView, id + " " + text ,Snackbar.LENGTH_LONG);

          snackbar.setAction("Dismiss", new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                snackbar.dismiss();
            }
        });
        snackbar.setActionTextColor(Color.MAGENTA);
        snackbar.show();
    }


    UserBoxGLBFragment fragment = new UserBoxGLBFragment();
    private void addSelectedCardToGlobalUserBox(int position) {
        ImageAdapter imageAdapter = new ImageAdapter(getContext());
        fragment.addInteger(imageAdapter.getmThumbIds(0)); // pass the Drawable's Integer value to the fragmnet
        Toast.makeText(getActivity(), "Selected icon: " + imageAdapter.getmThumbIds(position), Toast.LENGTH_SHORT).show();
    }

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

        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_main_screen, container, false);

        gridView = view.findViewById(R.id.gridViewLayout);
        gridView.setAdapter(new ImageAdapter(getContext())); // used to set the contents of the GridView-in this case images-
        registerForContextMenu(gridView);

        // When an item from the GridView gets clicked
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // Create a new Intent...
                Toast.makeText(getActivity(), "Position: " + position, Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(getContext(),CardViewActivity.class);
                intent.putExtra("Card Index",position);
                intent.putExtra("SCREEN_WIDTH",1080);
                startActivity(intent);
            }
        });
        return view;
    }

}

UserBoxGLBFragment.java :

public class UserBoxGLBFragment extends Fragment {

    GridView globalGridView;
    UserBoxGlbImageAdapter adapter = new UserBoxGlbImageAdapter(getContext());

    public UserBoxGLBFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_user_box_glb, container, false);
        globalGridView = view.findViewById(R.id.userBoxGlbGridView);
        globalGridView.setAdapter(adapter);
        return view;
    }

    public void addInteger(Integer integer) {
        adapter.addDrawableToList(integer);
    }
}

UserBoxGLBImageAdapter.java:

public class UserBoxGlbImageAdapter extends BaseAdapter {

    private Context mContext;

    private List<Integer> mGLBIcons = new ArrayList<>();

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

    public List<Integer> getIcons() {
        return mGLBIcons;
    }

    @Override
    public int getCount() {
        return mGLBIcons.size();
    }

    @Override
    public Object getItem(int i) {
        return mGLBIcons.get(i);
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        // If it's not recycled, initialize some attributes
        if (convertView == null) {
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(225, 225));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }
         //Drawable drbl = mContext.getResources().getDrawable(mGLBIcons.get(0));
        Toast.makeText(mContext, "Size:" + getCount(), Toast.LENGTH_SHORT).show();
        imageView.setImageResource(getIcons().get(0));
        return imageView;
    }

    public void addDrawableToList(Integer integer) {
        mGLBIcons.add(integer);
        notifyDataSetChanged();
    }
}

Sorry for the long post b ut i really need your help on this one!!!!

Can you push your code to a Github/Bitbucket repo so Community members can use your code and understand the issue you have to suggest solutions. Staring at a load of code is hard. Pulling a repo is a good way to get a solution.

I'll try to format your code in your post too ...

Steve.

Mike Papamichail
Mike Papamichail
4,883 Points

Thank you very much for the quick answer @Steve Hunter , I'll get to it asap. One question, do i need to push my whole project or just the code above?

Also, thanks for formatting my code, i don't know what i did wrong there.

Cheers

Sorry for being slow to respond; I'm away with work today. If you push the whole project, I can replicate the issue here and try to figure out a solution.

I can see you've added the repo link I'll pull that down into Studio later and have a tinker with the code. If you change anything, make sure to push the changes to the remote so I get the updates here too. If I change anything, I can do the same so you can merge my code with yours.

[EDIT] Done that - are there really no import statements at the top of any of your classes?

Steve.