JLT
JLT

Reputation: 3172

Unable To Change The Image Resource Of Image Button In A Grid View

The GridView in my app consists of multiple ImageButtons. When an ImageButton is tapped, the image resource of that ImageButton will change.

This is the int array of the image resource ids when an ImageButton is not tapped.

private final int mineIcons[] = 
{
    R.drawable.habit,
    R.drawable.story,
    R.drawable.submenu_voice_message,
    R.drawable.study,
    R.drawable.guess,
    R.drawable.poem,
    R.drawable.add
};

This is the int array of the image resource ids when an ImageButton is tapped.

private final int mineIconsSelected[] = 
{
    R.drawable.habit_selected,
    R.drawable.story_selected,
    R.drawable.submenu_voice_message_selected,
    R.drawable.study_selected,
    R.drawable.guess_selected,
    R.drawable.poem_selected,
    R.drawable.add
};

When this activity is loaded, I want that the first ImageButton in the GridView is in state of "tapped". So I set this int array of image resource ids for default image resource of the ImageButtons when the ImageButtons are loaded.

private final int mineIconsDefault[] = 
{
    R.drawable.habit_selected,
    R.drawable.story,
    R.drawable.submenu_voice_message,
    R.drawable.study,
    R.drawable.guess,
    R.drawable.poem,
    R.drawable.add
};

This is the complete code of the Fragment

public class MineFragment extends Fragment { private final static String LOG_TAG = "MineFragment";

private final int mineIcons[] = 
{
    R.drawable.habit,
    R.drawable.story,
    R.drawable.submenu_voice_message,
    R.drawable.study,
    R.drawable.guess,
    R.drawable.poem,
    R.drawable.add
};

private final int mineIconsSelected[] = 
{
    R.drawable.habit_selected,
    R.drawable.story_selected,
    R.drawable.submenu_voice_message_selected,
    R.drawable.study_selected,
    R.drawable.guess_selected,
    R.drawable.poem_selected,
    R.drawable.add
};

private SparseArray<ImageButton> submenuIconArray = new SparseArray<ImageButton>();
private SubMenuListAdapter submenuListAdapter = new SubMenuListAdapter();
private MineListAdapter mineListAdapter = new MineListAdapter();

private GridView gvSubmenu;
private ListView lvMine;

private int selectedItemNumber = 0;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
}

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

    return view;
}

private void init(View view)
{
    lvMine = (ListView)view.findViewById(R.id.lv_mine);
    lvMine.setAdapter(mineListAdapter);

    gvSubmenu = (GridView)getActivity().findViewById(android.R.id.content).findViewById(R.id.gv_submenu);
    gvSubmenu.setAdapter(submenuListAdapter);
}

public void showSubmenu()
{
    if(gvSubmenu != null)
    {
        gvSubmenu.setVisibility(View.VISIBLE);
    }
}

public void hideSubmenu()
{
    if(gvSubmenu != null)
    {
        gvSubmenu.setVisibility(View.GONE);
    }
}

private class SubMenuListAdapter extends BaseAdapter
{       
    private final int mineIconsDefault[] = 
    {
        R.drawable.habit_selected,
        R.drawable.story,
        R.drawable.submenu_voice_message,
        R.drawable.study,
        R.drawable.guess,
        R.drawable.poem,
        R.drawable.add
    };

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

    @Override
    public Object getItem(int position) 
    {
        return mineIconsDefault[position];
    }

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

    @Override
    public View getView(final int position, View convertView, ViewGroup root) 
    {
        if(convertView == null)
        {
            convertView = LayoutInflater.from(getActivity().getApplicationContext()).inflate(R.layout.list_item_submenu, root, false);
        }

        ImageButton ibSubmenuIcon = (ImageButton)convertView.findViewById(R.id.ib_item_submenu_icon);
        ibSubmenuIcon.setImageResource(mineIconsDefault[position]);
        ibSubmenuIcon.setOnClickListener(new OnClickListener() 
        {   
            @Override
            public void onClick(View arg0) 
            {
                submenuIconArray.get(selectedItemNumber).setImageResource(mineIcons[selectedItemNumber]);
                submenuIconArray.get(position).setImageResource(mineIconsSelected[position]);

                selectedItemNumber = position;
            }
        });

        submenuIconArray.append(position, ibSubmenuIcon);

        return convertView;
    }
}

private class MineListAdapter extends BaseAdapter
{
    //temp 
    private String[] tempListItems = {"item 1", "item 2", "item 3", "item 4", "item 5"};

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

    @Override
    public Object getItem(int arg0) 
    {
        return tempListItems[arg0];
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup root) 
    {
        if(convertView == null)
        {
            convertView = LayoutInflater.from(getActivity().getApplicationContext()).inflate(R.layout.list_item_layout_1, root, false);
        }

        ImageView ivItemIcon = (ImageView)convertView.findViewById(R.id.iv_item_icon);
        TextView tvItemLabel = (TextView)convertView.findViewById(R.id.tv_item_label);

        tvItemLabel.setText(tempListItems[position]);

        return convertView;
    }
}

}

I use SparseArray to store each ImageButton loaded in the GridView so that later when I have to change the image resource of an ImageButton, I will just have to get that ImageButton from the SparseArray and then set its image resource to the corresponding one in the mineIconsSelected int array. Before doing that I will make sure that the image resource of the ImageButton I previously tapped will be set to the corresponding one in the mineIcons int array.

Now, the strange problem comes in.

I was able to successfully change the image resource of any ImageButton stored in the SparseArray upon tapping, EXCEPT the FIRST one. No matter how many times I check my code, make Logs, I can't find where the problem is.

Please help me. Many Thanks!

Upvotes: 0

Views: 175

Answers (1)

Trevor Carothers
Trevor Carothers

Reputation: 2260

I'd strongly suggest simplifying your code first. After doing so your problem will either go away or be much easier to debug. It will be a bit tedious upfront since you have so many buttons, but it will make your code a lot more manageable. Create a simple selector drawable file for each button. i.e. for the habit button: habit_selector.xml (place in drawable folder)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/habit" android:android:state_selected="true"/>
    <item android:drawable="@drawable/habit_selected"/>
</selector>

Then set it on your button:

private final int mineIconSelectors[] = 
{
    R.drawable.habit_selector,
    R.drawable.story_selector,
    R.drawable.submenu_voice_message_selector,
    ...
}

    ...
    ImageButton ibSubmenuIcon = (ImageButton)convertView.findViewById(R.id.ib_item_submenu_icon);
    ibSubmenuIcon.setBackground(mineIconSelectors[position]);

Thus when the button is selected, Android will automatically switch the drawable asset for you.

Upvotes: 2

Related Questions