I am creating an android app in which the user can capture the images and these images are displayed in gridview.when the user wants to delete one or more images by touching the images i am getting an java index out of bounds exception.The example which i have seen has used the image adapter extending to a arrayadapter but i am using an image adapter which extends to base adapter. So i don't know because of it does the error occurs.
grid.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
final int checkedCount = grid.getCheckedItemCount();
mode.setTitle(checkedCount + " Selected");
adapter.toggleSelection(position);
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.delete_mode, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
// Calls getSelectedIds method from ListViewAdapter Class
SparseBooleanArray selected = adapter
.getSelectedIds();
// Captures all selected ids with a loop
for (int i = (selected.size() - 1); i >= 0; i--) {
if (selected.valueAt(i)) {
int selecteditem = (int) adapter
.getItem(selected.keyAt(i));
//Remove selected items following the ids
String imgPath = listOfImagesPath.get(selecteditem);
File file=new File(imgPath);
file.delete();
adapter.removeitem(selecteditem);
}
}
// Close CAB
mode.finish();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode actionMode) {
adapter.removeSelection();
}
});
Image adapter(which i have created):
public class ImageListAdapter extends BaseAdapter
{
private Context context;
private List<String> imgPic;
private SparseBooleanArray mSelectedItemsIds;
public ImageListAdapter(Context c, List<String> thePic)
{
context = c;
imgPic = thePic;
mSelectedItemsIds = new SparseBooleanArray();
}
public int getCount() {
if(imgPic != null)
return imgPic.size();
else
return 0;
}
//---returns the ID of an item---
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public void removeitem(int position){
imgPic.remove(position);
notifyDataSetChanged();
}
public void toggleSelection(int position) {
selectView(position, !mSelectedItemsIds.get(position));
}
public void removeSelection() {
mSelectedItemsIds = new SparseBooleanArray();
notifyDataSetChanged();
}
public void selectView(int position, boolean value) {
if (value)
mSelectedItemsIds.put(position, value);
else
mSelectedItemsIds.delete(position);
notifyDataSetChanged();
}
public int getSelectedCount() {
return mSelectedItemsIds.size();
}
public SparseBooleanArray getSelectedIds() {
return mSelectedItemsIds;
}
//---returns an ImageView view---
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView;
BitmapFactory.Options bfOptions=new BitmapFactory.Options();
bfOptions.inDither=false; //Disable Dithering mode
bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
bfOptions.inTempStorage=new byte[32 * 1024];
if (convertView == null) {
imageView = new ImageView(context);
imageView.setLayoutParams(new GridView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
imageView.setPadding(0, 0, 0, 0);
} else {
imageView = (ImageView) convertView;
}
FileInputStream fs = null;
Bitmap bm;
try {
fs = new FileInputStream(new File(imgPic.get(position).toString()));
if(fs!=null) {
bm=BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
imageView.setImageBitmap(bm);
imageView.setId(position);
imageView.setLayoutParams(new GridView.LayoutParams(200, 160));
}
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fs!=null) {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return imageView;
}
}
Image adapter(the example which i saw for deleting multiple images in grid)
public class ListViewAdapter extends ArrayAdapter<WorldPopulation> {
// Declare Variables
Context context;
LayoutInflater inflater;
List<WorldPopulation> worldpopulationlist;
private SparseBooleanArray mSelectedItemsIds;
public ListViewAdapter(Context context, int resourceId,
List<WorldPopulation> worldpopulationlist) {
super(context, resourceId, worldpopulationlist);
mSelectedItemsIds = new SparseBooleanArray();
this.context = context;
this.worldpopulationlist = worldpopulationlist;
inflater = LayoutInflater.from(context);
}
private class ViewHolder {
TextView rank;
TextView country;
TextView population;
ImageView flag;
}
public View getView(int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.listview_item, null);
// Locate the TextViews in listview_item.xml
holder.rank = (TextView) view.findViewById(R.id.rank);
holder.country = (TextView) view.findViewById(R.id.country);
holder.population = (TextView) view.findViewById(R.id.population);
// Locate the ImageView in listview_item.xml
holder.flag = (ImageView) view.findViewById(R.id.flag);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Capture position and set to the TextViews
holder.rank.setText(worldpopulationlist.get(position).getRank());
holder.country.setText(worldpopulationlist.get(position).getCountry());
holder.population.setText(worldpopulationlist.get(position)
.getPopulation());
// Capture position and set to the ImageView
holder.flag.setImageResource(worldpopulationlist.get(position)
.getFlag());
return view;
}
#Override
public void remove(WorldPopulation object) {
worldpopulationlist.remove(object);
notifyDataSetChanged();
}
public List<WorldPopulation> getWorldPopulation() {
return worldpopulationlist;
}
public void toggleSelection(int position) {
selectView(position, !mSelectedItemsIds.get(position));
}
public void removeSelection() {
mSelectedItemsIds = new SparseBooleanArray();
notifyDataSetChanged();
}
public void selectView(int position, boolean value) {
if (value)
mSelectedItemsIds.put(position, value);
else
mSelectedItemsIds.delete(position);
notifyDataSetChanged();
}
public int getSelectedCount() {
return mSelectedItemsIds.size();
}
public SparseBooleanArray getSelectedIds() {
return mSelectedItemsIds;
}
Error:
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.remove(ArrayList.java:403)
at nidhinkumar.gridcam.Cam$ImageListAdapter.removeitem(Cam.java:360)
at nidhinkumar.gridcam.Cam$4.onActionItemClicked(Cam.java:200)
at android.widget.AbsListView$MultiChoiceModeWrapper.onActionItemClicked(AbsListView.java:6693)
at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onActionItemClicked(PhoneWindow.java:3430)
at android.support.v7.view.SupportActionModeWrapper$CallbackWrapper.onActionItemClicked(SupportActionModeWrapper.java:168)
at android.support.v7.app.AppCompatDelegateImplV7$ActionModeCallbackWrapperV7.onActionItemClicked(AppCompatDelegateImplV7.java:1703)
at android.support.v7.app.AppCompatDelegateImplV7$ActionModeCallbackWrapperV7.onActionItemClicked(AppCompatDelegateImplV7.java:1703)
at android.support.v7.view.StandaloneActionMode.onMenuItemSelected(StandaloneActionMode.java:136)
I'm getting this error only when i try to delete the image after capturing.When i reload the page again and delete the image it works fine.
You might have problem here:
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
// Calls getSelectedIds method from ListViewAdapter Class
SparseBooleanArray selected = adapter
.getSelectedIds();
// Captures all selected ids with a loop
for (int i = (selected.size() - 1); i >= 0; i--) {
In this line
SparseBooleanArray selected = adapter
.getSelectedIds();
selected is not an array. so its size will always be one. and you are subtracting 1 from it thus making its size 0. Therefore, it'll always give array index out of bound exception whenever you'll try to access it.
A simple fiz may be this :
SparseBooleanArray[] selected = adapter
.getSelectedIds();
Related
I have a little bit problem.In my activity there is two Adapter one is for color selection and another is for size selection. While i clicked one of the item of color then recently the available size adapter should be change but i got problem in size adapter. it changes only when i click the size item. I research and try to solve problem but it doesnt works for me.
Here is my code.
AddToCartActivity.java
public class AddToCartActivity extends BaseActivity{
#Override
protected int getLayout() {
return R.layout.activity_add_to_cart;
}
#Override
protected void init() {
//api called here
}
// response of api
#Override
public void productDetail(ProductCommonModel productCommonModel,
ArrayList<ProductChildModel> productChildModels, HashMap<Integer,
ArrayList<ChildAttributeModel>> childWithAttribute, HashMap<Integer,
ArrayList<ChildImageModel>> childWithImages,
ArrayList<com.hazesoft.dokan.singleproductdetail.model.ColorModel>
colorModels, ArrayList<SizeModel> sizeModels,
ArrayList<RelatedProductModel> relatedProductModels) {
this.productCommonModel = productCommonModel;
this.productChildModels = productChildModels;
this.childWithAttribute = childWithAttribute;
this.childWithImages = childWithImages;
this.colorModels = colorModels;
this.sizeModels = sizeModels;
this.relatedProductModels = relatedProductModels;
tvProductName.setText(productCommonModel.getName());
if (productCommonModel.getSpecialPrice() == 0) {
tvSellingPrice.setText(getString(R.string.rs) + productCommonModel.getSellingPrice());
tvDiscount.setVisibility(View.GONE);
tvSpecialPrice.setVisibility(View.GONE);
} else {
tvSpecialPrice.setText(getString(R.string.rs) + productCommonModel.getSpecialPrice());
tvSellingPrice.setText(getString(R.string.rs) + productCommonModel.getSellingPrice());
tvSellingPrice.setPaintFlags(tvSellingPrice.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
tvDiscount.setText(productCommonModel.getDiscount() + getString(R.string.percentage));
}
setChildDetail(childWithAttribute, productChildModels);
setColorModel(colorModels);
setSizeModel(sizeModels);
quantity = Integer.parseInt(tvQuantityCart.getText().toString());
}
// setcolor adapter
private void setColorModel(ArrayList<ColorModel> colorModels) {
MyColorGridViewAdapter adapter = new MyColorGridViewAdapter(this, colorModels);
gvColor.setAdapter(adapter);
gvColor.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
adapter.setSelectedPostion(position);
adapter.notifyDataSetChanged();
}
});
}
// set size adapter
private void setSizeModel(ArrayList<SizeModel> sizeModels) {
sizeCustomModels = new ArrayList<>();
for(int i=0;i<sizeModels.size();i++){
sizeCustomModels.add(new SizeCustomModel(sizeModels.get(i).getAttName(),0));
}
setCustomSizeModelToAdapter(sizeCustomModels);
}
// this is code when i click color and change the size adapter but size doesnt change recently only changes when i click any item of the size
public void getSelectedC0lor(String color) {
selectedColor = color;
selectedSize=null;
sizeCustomModels = new ArrayList<>();
availableSize = new ArrayList<>();
for (int i = 0; i < skuColorSIzeList.size(); i++) {
if (skuColorSIzeList.get(i).getColor().equals(selectedColor)) {
availableSize.add(skuColorSIzeList.get(i).getSize());
}
}
for(int i=0;i<sizeModels.size();i++){
String size = null;
int status=0;
for(int j=0;j<availableSize.size();j++){
if(sizeModels.get(i).getAttName().equals(availableSize.get(j))){
size = sizeModels.get(i).getAttName();
status = 1;
break;
}else {
size = sizeModels.get(i).getAttName();
status = 0;
}
}
sizeCustomModels.add(new SizeCustomModel(size,status));
}
sizeRecylerAdapter.getNewModel(sizeCustomModels);
/*sizeRecylerAdapter = new MyCustomSizeRecylerAdapter(sizeCustomModels,this);
rvSize.setAdapter(sizeRecylerAdapter);
sizeRecylerAdapter.notifyDataSetChanged();*/
/*setCustomSizeModelToAdapter(sizeCustomModels);*/
}
}
MyColorGridViewAdapter.java
public class MyColorGridViewAdapter extends BaseAdapter {
Context context;
List<ColorModel> colorModelList;
String select_color;
boolean ch =false;
int checkPosition = -1;
public MyColorGridViewAdapter(Context context, List<ColorModel> colorModelList) {
this.context = context;
this.colorModelList = colorModelList;
}
public void setSelectedPostion(int postion){
this.checkPosition = postion;
}
#Override
public int getCount() {
return colorModelList.size();
}
#Override
public Object getItem(int position) {
return colorModelList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView==null){
convertView = LayoutInflater.from(context).inflate(R.layout.custom_color_list_item,null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
Picasso.with(context).load(colorModelList.get(position).getImage()).into(holder.ivImage);
holder.tvColorName.setText(colorModelList.get(position).getAttName());
if(checkPosition==position){
holder.ivChecked.setVisibility(View.VISIBLE);
select_color = colorModelList.get(position).getAttName();
if( context instanceof AddToCartActivity){
((AddToCartActivity) context).getSelectedC0lor(select_color);
}
}else {
holder.ivChecked.setVisibility(View.GONE);
}
if(colorModelList.size()==1){
holder.ivChecked.setVisibility(View.VISIBLE);
select_color = colorModelList.get(position).getAttName();
if( context instanceof AddToCartActivity){
((AddToCartActivity) context).getSelectedC0lor(select_color);
}
}
return convertView;
}
class ViewHolder{
#BindView(R.id.view)
LinearLayout view;
#BindView(R.id.tv_color_name)
TextViewHelper tvColorName;
#BindView(R.id.iv_image)
ImageView ivImage;
#BindView(R.id.iv_checked)
ImageView ivChecked;
public ViewHolder(View view) {
ButterKnife.bind(this,view);
}
}
}
MyCustomSizeRecylerAdapter.java
public class MyCustomSizeRecylerAdapter extends RecyclerView.Adapter<MyCustomSizeRecylerAdapter.MyViewHolder> {
ArrayList<SizeCustomModel> sizeModels;
Context context;
int checkPosition = -1;
String selectedSize;
public MyCustomSizeRecylerAdapter(ArrayList<SizeCustomModel> sizeModels, Context context) {
this.sizeModels = sizeModels;
this.context = context;
}
public void getNewModel(ArrayList<SizeCustomModel> customModels) {
sizeModels.clear();
this.sizeModels = customModels;
selectedSize = null;
Log.d("sizemodel", "getNewModel: " + new Gson().toJson(sizeModels));
notifyDataSetChanged();
}
public void getSelectedPosition(int position) {
checkPosition = position;
notifyDataSetChanged();
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.size_adapter, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tv_sizeName.setText(sizeModels.get(position).getSize());
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
if (sizeModels.get(position).getStock_Status() == 0) {
holder.ll_mainview.setClickable(false);
holder.ll_sizeAdapter.setBackgroundResource(R.color.blue_700);
} else if (sizeModels.get(position).getStock_Status() == 1) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
if (checkPosition == position) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_green);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.white));
selectedSize = sizeModels.get(position).getSize();
if (context instanceof AddToCartActivity) {
((AddToCartActivity) context).getSelectSize(selectedSize);
}
} else {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.tv_black));
}
if (sizeModels.size() == 1) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_green);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.white));
selectedSize = sizeModels.get(position).getSize();
if (context instanceof AddToCartActivity) {
((AddToCartActivity) context).getSelectSize(selectedSize);
}
}
}
}
#Override
public int getItemCount() {
return sizeModels.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
#BindView(R.id.tv_sizeName)
TextView tv_sizeName;
#BindView(R.id.ll_sizeAdapter)
LinearLayout ll_sizeAdapter;
#BindView(R.id.main_view)
LinearLayout ll_mainview;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
At first both adapter will set data and after click color item the size adapter must be change but it only changes when i click any of the item. adapter.notifyDataSetChanged() doesnt work here for me.
Both Adapter set
When i click color item but doesnt change size adapter
when i click size item only change size adapter
Use Interface to bridge with two adapter and communicate with each other.
I'm making NLevel expandable list using listview. I've added checkbox only last level data in list view. I have stuck in below scenario.
If I check checkbox then when I expand listview means checkbox gets automatically unchecked.I don't want it to be like that. If I checked checkbox it should stay checked until I uncheck manually.
Please anyone help me!! It's been two days I stuck here.
Here goes my code:
MainActivity.java
public class MainActivity extends Activity {
List<NLevelItem> list;
ListView listView;
Context context;
Button checkButton;
ArrayList<String>tempList;
CheckBox selected = null; //Make only one selection at a time
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);
list = new ArrayList<NLevelItem>();
context = this;
checkButton = (Button)findViewById(R.id.buttons);
tempList = new ArrayList<String>();
//here we create 5 grandparent (top level) NLevelItems
//then foreach grandparent create a random number of parent (second level) NLevelItems
//then foreach parent create a random number of children (third level) NLevelItems
//we pass in an anonymous instance of NLevelView to the NLevelItem, this NLevelView is
//what supplies the NLevelAdapter with a View for this NLevelItem
Random rng = new Random();
final LayoutInflater inflater = LayoutInflater.from(this);
for (int i = 0; i < 5; i++) {
final NLevelItem grandParent = new NLevelItem(new SomeObject("GrandParent "+i),null, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.GREEN);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(grandParent);
int numChildren = rng.nextInt(4) + 1;
for (int j = 0; j < numChildren; j++) {
NLevelItem parent = new NLevelItem(new SomeObject("Parent "+j),grandParent, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.YELLOW);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(parent);
int children = rng.nextInt(3)+1;
for(int x=0; x<children;x++){
final NLevelItem childs = new NLevelItem(new SomeObject("Parent1 "+x),parent, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.BLUE);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(childs);
int grandChildren = rng.nextInt(5)+1;
for( int k = 0; k < grandChildren; k++) {
NLevelItem child = new NLevelItem(new SomeObject("child "+k),childs, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.check_list, null);
TextView tv = (TextView) view.findViewById(R.id.checktextView);
final String name = (String) ((SomeObject) item.getWrappedObject()).getName();
final CheckBox checkBox = (CheckBox)view.findViewById(R.id.check);
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(selected != null){ //Edit
selected.setChecked(false);
}
selected = checkBox; //Edit
if(checkBox.isChecked()){
tempList.add((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
else {
tempList.remove((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
}
});
//tv.setBackgroundColor(Color.GRAY);
tv.setText(name);
return view;
}
});
list.add(child);
}
}
}
}
NLevelAdapter adapter = new NLevelAdapter(list);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
((NLevelAdapter)listView.getAdapter()).toggle(arg2);
((NLevelAdapter)listView.getAdapter()).getFilter().filter();
}
});
checkButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i=0;i<tempList.size();i++){
Toast.makeText(context,tempList.get(i),Toast.LENGTH_LONG).show();
}
}
});
}
class SomeObject {
public String name;
public SomeObject(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}
NLevelAdapter.java
public class NLevelAdapter extends BaseAdapter {
List<NLevelItem> list;
List<NLevelListItem> filtered;
public void setFiltered(ArrayList<NLevelListItem> filtered) {
this.filtered = filtered;
}
public NLevelAdapter(List<NLevelItem> list) {
this.list = list;
this.filtered = filterItems();
}
#Override
public int getCount() {
return filtered.size();
}
#Override
public NLevelListItem getItem(int arg0) {
return filtered.get(arg0);
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
return getItem(arg0).getView();
}
public NLevelFilter getFilter() {
return new NLevelFilter();
}
class NLevelFilter {
public void filter() {
new AsyncFilter().execute();
}
class AsyncFilter extends AsyncTask<Void, Void, ArrayList<NLevelListItem> > {
#Override
protected ArrayList<NLevelListItem> doInBackground(Void...arg0) {
return (ArrayList<NLevelListItem>)filterItems();
}
#Override
protected void onPostExecute(ArrayList<NLevelListItem> result) {
setFiltered(result);
NLevelAdapter.this.notifyDataSetChanged();
}
}
}
public List<NLevelListItem> filterItems() {
List<NLevelListItem> tempfiltered = new ArrayList<NLevelListItem>();
OUTER: for (NLevelListItem item : list) {
//add expanded items and top level items
//if parent is null then its a top level item
if(item.getParent() == null) {
tempfiltered.add(item);
} else {
//go through each ancestor to make sure they are all expanded
NLevelListItem parent = item;
while ((parent = parent.getParent())!= null) {
if (!parent.isExpanded()) {
//one parent was not expanded
//skip the rest and continue the OUTER for loop
continue OUTER;
}
}
tempfiltered.add(item);
}
}
return tempfiltered;
}
public void toggle(int arg2) {
filtered.get(arg2).toggle();
}
}
Thanks in advance!!
i think you need to store the checkbox state in a boolean (is checked), and reflect that on the view, when getView() is called.
1- Add boolean checked to NLevelItem :
private boolean checked = false;
//add setter: setChecked(boolean)
//add getter isChecked()
2- Use that boolean in getView() (last one where checkbox is added)
#Override
public View getView(final NLevelItem item) {
// .......
final CheckBox checkBox = (CheckBox)view.findViewById(R.id.check);
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//store checkbox state, note that NLevelItem item might need to be defined with 'final'
item.setChecked(checkBox.isChecked());
if(checkBox.isChecked()){
tempList.add((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
else {
tempList.remove((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
}//onClick()
}//setOnClickListener()
//update checkbox state from the corresponding NLevelItem
checkBox.setChecked(item.isChecked());
//.......
}//getView()
-EDIT:
to select 1 item, you need to iterate all items, set checked = false, but 1
i am not sure if you have to do it on:
List<NLevelItem> list;
or
List<NLevelListItem> filtered;
in the adapter class
private void selectOnly(int position){
for(int a=0;a<list.size();a++){
if(a == position){
list.get(a).setChecked(true);
continue;
}
list.get(a).setChecked(false);
}//for loop
notifyDataSetChanged(); // to update views (checkbox state)
}
Usage: selectOnly(15);
Use ViewHolder class to set and get Tag like this:
public class ListAdapter extends BaseAdapter {
private Context con;
private List<String> dataLt;
private static LayoutInflater inflater = null;
public ListAdapter(Context context, List<String> dataList){
con = context;
dataLt = dataList;
inflater = (LayoutInflater)con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return dataLt.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder;
if(convertView==null){
/****** Inflate tabitem.xml file for each row ( Defined below ) *******/
vi = inflater.inflate(R.layout.list_item_search, null);
/****** View Holder Object to contain tabitem.xml file elements ******/
holder = new ViewHolder();
holder.textView = (TextView) vi.findViewById(R.id.textView);
/************ Set holder with LayoutInflater ************/
vi.setTag( holder );
}
else
holder=(ViewHolder)vi.getTag();
return vi;
}
public static class ViewHolder{
TextView textView;
}
}
Hope this may help.
I have a bunch of images from sdcard that are load asynchronously on a gridview. Everything works fine, but when accessing a multi select contextual action menu by long clicking in any image the entire activity reloads and all images are loaded again. How to prevent it?
Myadapter
public class PhotosGridViewImageAdapter extends BaseAdapter {
AsyncTaskLoadFiles myAsyncTaskLoadFiles;
public class AsyncTaskLoadFiles extends AsyncTask<Void, String, Void> {
File targetDirector;
PhotosGridViewImageAdapter myTaskAdapter;
public AsyncTaskLoadFiles(PhotosGridViewImageAdapter adapter) {
myTaskAdapter = adapter;
}
#Override
protected void onPreExecute() {
String ExternalStorageDirectoryPath = Environment
.getExternalStorageDirectory().getAbsolutePath();
String targetPath = ExternalStorageDirectoryPath + File.separator + AppConstant.PHOTO_ALBUM + File.separator;
targetDirector = new File(targetPath);
myTaskAdapter.clear();
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
File[] files = targetDirector.listFiles();
Arrays.sort(files);
for (File file : files) {
publishProgress(file.getAbsolutePath());
if (isCancelled()) break;
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
myTaskAdapter.add(values[0]);
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Void result) {
myTaskAdapter.notifyDataSetChanged();
super.onPostExecute(result);
}
}
ArrayList<String> itemList = new ArrayList<String>();
void add(String path) {
itemList.add(path);
}
void clear() {
itemList.clear();
}
void remove(int index){
itemList.remove(index);
}
private Activity _activity;
private ArrayList<String> _filePaths = new ArrayList<String>();
private int imageWidth;
public PhotosGridViewImageAdapter(Activity activity, ArrayList<String> filePaths,
int imageWidth) {
this._activity = activity;
this._filePaths = filePaths;
this.imageWidth = imageWidth;
}
#Override
public int getCount() {
return this._filePaths.size();
}
#Override
public Object getItem(int position) {
return this._filePaths.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
final ImageView imageView;
if (convertView == null) {
imageView = new ImageView(_activity);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth,
imageWidth));
convertView = imageView;
holder = new ViewHolder();
holder.image = imageView;
holder.position = position;
convertView.setTag(holder);
} else {
//imageView = (ImageView) convertView;
holder = (ViewHolder) convertView.getTag();
((ImageView)convertView).setImageBitmap(null);
}
new AsyncTask<ViewHolder, Void, Bitmap>() {
private ViewHolder v;
// get screen dimensions
#Override
protected Bitmap doInBackground(ViewHolder... params) {
v = params[0];
Bitmap image = decodeFile(_filePaths.get(position), imageWidth,
imageWidth);
//imageView.setImageBitmap(image);
return image;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
v.image.setImageBitmap(result);
}
}.execute(holder);
return convertView;
}
/*
* Resizing image size
*/
public Bitmap decodeFile(String filePath, int WIDTH, int HEIGHT) {
try {
File f = new File(filePath);
if(filePath.contains(".jpg")) {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
final int REQUIRED_WIDTH = WIDTH;
final int REQUIRED_HEIGHT = HEIGHT;
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_WIDTH
&& o.outHeight / scale / 2 >= REQUIRED_HEIGHT)
scale *= 2;
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
}else if(filePath.contains(".mp4")){
return ThumbnailUtils.createVideoThumbnail(filePath, 0);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
class ViewHolder {
ImageView image;
int position;
}
}
Contextual action menu code
public class MultiChoiceModeListener implements
GridView.MultiChoiceModeListener {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.contextual_action_menu, menu);
//mode.setTitle("Select Items");
mode.setTitle("1 item selected");
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Respond to clicks on the actions in the CAB
switch (item.getItemId()) {
case R.id.delete:
SparseBooleanArray checked = gridView.getCheckedItemPositions();
try {
int len = checked.size();
for (int i = 0; i < len; i++) {
if (checked.valueAt(i)) {
Integer position = checked.keyAt(i);
//deleteToMessageHistory(position);
}
}
}catch (Exception i){
Toast.makeText(PhotosGridViewActivity.this, "Message was not deleted. Try again.", Toast.LENGTH_SHORT).show();
}
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
public void onDestroyActionMode(ActionMode mode) {
}
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
int selectCount = gridView.getCheckedItemCount();
switch (selectCount) {
case 1:
mode.setTitle("1 item selected");
break;
default:
mode.setTitle("" + selectCount + " items selected");
break;
}
}
}
I appreciate any help!
==UPDATE==
Here is the MainActivity code:
public class PhotosGridViewActivity extends Activity {
private PhotosUtils utils;
private ArrayList<String> imagePaths = new ArrayList<String>();
private PhotosGridViewImageAdapter adapter;
private GridView gridView;
private int columnWidth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initilizing Grid View
InitilizeGridLayout();
}
private void InitilizeGridLayout() {
setContentView(R.layout.photos_grid_view);
utils = new PhotosUtils(PhotosGridViewActivity.this);
gridView = (GridView) findViewById(R.id.grid_view);
// loading all image paths from SD card
imagePaths = utils.getFilePaths();
Resources r = getResources();
float padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
AppConstant.GRID_PADDING, r.getDisplayMetrics());
columnWidth = (int) ((utils.getScreenWidth() - ((AppConstant.NUM_OF_COLUMNS + 1) * padding)) / AppConstant.NUM_OF_COLUMNS);
gridView.setNumColumns(AppConstant.NUM_OF_COLUMNS);
gridView.setColumnWidth(columnWidth);
gridView.setStretchMode(GridView.NO_STRETCH);
gridView.setPadding((int) padding, (int) padding, (int) padding,
(int) padding);
gridView.setHorizontalSpacing((int) padding);
gridView.setVerticalSpacing((int) padding);
gridView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
gridView.setMultiChoiceModeListener(new MultiChoiceModeListener());
// Gridview adapter
adapter = new PhotosGridViewImageAdapter(PhotosGridViewActivity.this, imagePaths,
columnWidth);
// setting grid view adapter
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
gridView.getItemAtPosition(position);
Intent i = new Intent(PhotosGridViewActivity.this, PhotosScreenViewActivity.class);
i.putExtra("position", position);
PhotosGridViewActivity.this.startActivity(i);
}
});
}
public class MultiChoiceModeListener implements
GridView.MultiChoiceModeListener {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.contextual_action_menu, menu);
//mode.setTitle("Select Items");
mode.setTitle("1 item selected");
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Respond to clicks on the actions in the CAB
switch (item.getItemId()) {
case R.id.delete:
SparseBooleanArray checked = gridView.getCheckedItemPositions();
try {
int len = checked.size();
for (int i = 0; i < len; i++) {
if (checked.valueAt(i)) {
Integer position = checked.keyAt(i);
//deleteToMessageHistory(position);
}
}
}catch (Exception i){
Toast.makeText(PhotosGridViewActivity.this, "Message was not deleted. Try again.", Toast.LENGTH_SHORT).show();
}
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
public void onDestroyActionMode(ActionMode mode) {
}
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
int selectCount = gridView.getCheckedItemCount();
switch (selectCount) {
case 1:
mode.setTitle("1 item selected");
break;
default:
mode.setTitle("" + selectCount + " items selected");
break;
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(co.glurl.appoid.R.menu.photo_gallery, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add:
/** Go to the user's add photos. */
startActivity(new Intent(this, PhotoIntentActivity.class));
break;
//case R.id.settings:
/** Go to the user's settings photos. */
// startActivity(new Intent(this, PhotoGridSettings.class));
// break;
default:
return super.onContextItemSelected(item);
}
return true;
}
}
My soluction. Thanks to #pushbit for guiding me through it.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ImageView imageView = (ImageView) convertView;
if (imageView == null) {
imageView = new ImageView(_activity);
}
// Trigger the download of the URL asynchronously into the image view.
if(_filePaths.get(position).contains(".jpg")) {
Picasso.with(_activity)
.load(new File(_filePaths.get(position)))
.resize(imageWidth, imageWidth)
.centerCrop()
.tag(_activity)
.into(imageView);
}else if(_filePaths.get(position).contains(".mp4")){
VideoRequestHandler videoRequestHandler;
Picasso picassoInstance;
videoRequestHandler=new VideoRequestHandler();
picassoInstance = new Picasso.Builder(_activity.getApplicationContext())
.addRequestHandler(videoRequestHandler)
.build();
picassoInstance
.load(videoRequestHandler.SCHEME_VIDEO+":"+_filePaths.get(position))
.resize(imageWidth, imageWidth)
.centerCrop()
.tag(_activity)
.into(imageView);
}
return imageView;
}
public static boolean deleteToPhotoAlbum(Integer position) {
File file = new File(_filePaths.get(position));
boolean deleted = file.delete();
return deleted;
}
public class VideoRequestHandler extends RequestHandler {
public String SCHEME_VIDEO = "video";
#Override
public boolean canHandleRequest(Request data)
{
String scheme = data.uri.getScheme();
return (SCHEME_VIDEO.equals(scheme));
}
#Override
public Result load(Request data, int arg1) throws IOException
{
Bitmap bm = ThumbnailUtils.createVideoThumbnail(data.uri.getPath(), MediaStore.Images.Thumbnails.MINI_KIND);
return new Result(bm, Picasso.LoadedFrom.DISK);
}
}
In my app I need to show images inside a expandableListView and it has to be a gridview of images, and these images can be selectable so I have an expandableListAdapter and inside of it I'm implementing a gridview adapter,
the images are showing fine as you can see in the picture 1, now what I'm trying to achieve is the picture 2, how can I pass the groupPosition and the childPosition to the gridAdapter and whe I click on the image make it highlight? :
Picture 2:
public class ExpandListAdapter extends BaseExpandableListAdapter {
public static final int CHOICE_MODE_MULTIPLE = AbsListView.CHOICE_MODE_MULTIPLE;
public static final int CHOICE_MODE_MULTIPLE_MODAL = AbsListView.CHOICE_MODE_MULTIPLE_MODAL;
/**
* No child could be selected
*/
public static final int CHOICE_MODE_NONE = AbsListView.CHOICE_MODE_NONE;
/**
* One single choice per group
*/
public static final int CHOICE_MODE_SINGLE_PER_GROUP = AbsListView.CHOICE_MODE_SINGLE;
/**
* One single choice for all the groups
*/
public static final int CHOICE_MODE_SINGLE_ABSOLUTE = 10001;
private Context context;
private ArrayList<Group> groups;
private ArrayList<ArrayList<Child>> child = new ArrayList();
private ArrayList<Child> listchild;
private GridAdapter adapter;
private CustomGridView gridView;
private SparseArray<SparseBooleanArray> checkedPositions;
private static final String LOG_TAG = ExpandListAdapter.class.getSimpleName();
private int choiceMode = CHOICE_MODE_MULTIPLE;
public ExpandListAdapter(Context context, ArrayList<Group> groups) {
this.context = context;
this.groups = groups;
checkedPositions = new SparseArray<SparseBooleanArray>();
child = new ArrayList();
for (int i = 0; i < groups.size(); i++) {
child.add(i, groups.get(i).getItems());
}
}
public ExpandListAdapter(Context context, ArrayList<Group> children, int choiceMode) {
this(context, children);
// For now the choice mode CHOICE_MODE_MULTIPLE_MODAL
// is not implemented
if (choiceMode == CHOICE_MODE_MULTIPLE_MODAL) {
throw new RuntimeException("The choice mode CHOICE_MODE_MULTIPLE_MODAL " +
"has not implemented yet");
}
this.choiceMode = choiceMode;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return child.get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public View getChildView(final int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.gridview, null);
}
listchild = new ArrayList<Child>();
for (int j = 0; j < groups.get(groupPosition).getItems().size(); j++) {
listchild.add(child.get(groupPosition).get(j));
}
gridView = (CustomGridView) convertView.findViewById(R.id.GridView_toolbar);
gridView.setExpanded(true);
adapter = new GridAdapter(context, listchild, checkedPositions, groupPosition, childPosition);
gridView.setAdapter(adapter);// Adapter
gridView.setChoiceMode(CustomGridView.CHOICE_MODE_MULTIPLE);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
setClicked(groupPosition, childPosition);
System.out.println("position" + checkedPositions.get(groupPosition));
if (checkedPositions.get(groupPosition) != null) {
boolean isChecked = checkedPositions.get(groupPosition).get(childPosition);
if(!isChecked){
}
} else {
System.out.println("false");
}
}
});
return convertView;
}
public void setClicked(int groupPosition, int childPosition) {
switch (choiceMode) {
case CHOICE_MODE_MULTIPLE:
SparseBooleanArray checkedChildPositionsMultiple = checkedPositions.get(groupPosition);
// if in the group there was not any child checked
if (checkedChildPositionsMultiple == null) {
checkedChildPositionsMultiple = new SparseBooleanArray();
// By default, the status of a child is not checked
// So a click will enable it
checkedChildPositionsMultiple.put(childPosition, true);
checkedPositions.put(groupPosition, checkedChildPositionsMultiple);
} else {
boolean oldState = checkedChildPositionsMultiple.get(childPosition);
checkedChildPositionsMultiple.put(childPosition, !oldState);
}
break;
// TODO: Implement it
case CHOICE_MODE_MULTIPLE_MODAL:
throw new RuntimeException("The choice mode CHOICE_MODE_MULTIPLE_MODAL " +
"has not implemented yet");
case CHOICE_MODE_NONE:
checkedPositions.clear();
break;
case CHOICE_MODE_SINGLE_PER_GROUP:
SparseBooleanArray checkedChildPositionsSingle = checkedPositions.get(groupPosition);
// If in the group there was not any child checked
if (checkedChildPositionsSingle == null) {
checkedChildPositionsSingle = new SparseBooleanArray();
// By default, the status of a child is not checked
checkedChildPositionsSingle.put(childPosition, true);
checkedPositions.put(groupPosition, checkedChildPositionsSingle);
} else {
boolean oldState = checkedChildPositionsSingle.get(childPosition);
// If the old state was false, set it as the unique one which is true
if (!oldState) {
checkedChildPositionsSingle.clear();
checkedChildPositionsSingle.put(childPosition, !oldState);
} // Else does not allow the user to uncheck it
}
break;
// This mode will remove all the checked positions from other groups
// and enable just one from the selected group
case CHOICE_MODE_SINGLE_ABSOLUTE:
checkedPositions.clear();
SparseBooleanArray checkedChildPositionsSingleAbsolute = new SparseBooleanArray();
checkedChildPositionsSingleAbsolute.put(childPosition, true);
checkedPositions.put(groupPosition, checkedChildPositionsSingleAbsolute);
break;
}
// Notify that some data has been changed
notifyDataSetChanged();
Log.v(LOG_TAG, "List position updated");
Log.v(LOG_TAG, PrintSparseArrays.sparseArrayToString(checkedPositions));
}
public void setChoiceMode(int choiceMode) {
this.choiceMode = choiceMode;
// For now the choice mode CHOICE_MODEL_MULTIPLE_MODAL
// is not implemented
if (choiceMode == CHOICE_MODE_MULTIPLE_MODAL) {
throw new RuntimeException("The choice mode CHOICE_MODE_MULTIPLE_MODAL " +
"has not implemented yet");
}
checkedPositions.clear();
Log.v(LOG_TAG, "The choice mode has been changed. Now it is " + this.choiceMode);
}
#Override
public int getChildrenCount(int nGroup) {
return 1;
}
#Override
public Object getGroup(int groupPosition) {
return groups.get(groupPosition);
}
#Override
public int getGroupCount() {
return groups.size();
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
Group group = (Group) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater inf = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = inf.inflate(R.layout.group_item, null);
}
ExpandableListView mExpandableListView = (ExpandableListView) parent;
mExpandableListView.expandGroup(groupPosition);
TextView tv = (TextView) convertView.findViewById(R.id.group_name);
tv.setText(group.getName());
return convertView;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
GridAdapter:
public class GridAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<Child> child;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
private SparseArray<SparseBooleanArray> checkedPositions;
int groupPosition, childPosition;
public GridAdapter(Context context, ArrayList<Child> childValues, SparseArray<SparseBooleanArray> checkedPositions, int groupPosition, int childPosition) {
mContext = context;
child = childValues;
this.checkedPositions = checkedPositions;
this.childPosition = childPosition;
this.groupPosition = groupPosition;
}
#Override
public int getCount() {
return child.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
NetworkImageView i;
childPosition = position;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.child_item, null);
holder = new ViewHolder();
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
i = (NetworkImageView) convertView
.findViewById(R.id.flag);
i.setImageUrl(String.valueOf(child.get(childPosition).getImage()), imageLoader);
convertView.setTag(holder);
System.out.println("position" + checkedPositions.get(groupPosition));
if (checkedPositions.get(groupPosition) != null) {
boolean isChecked = checkedPositions.get(groupPosition).get(childPosition);
i.setBackgroundResource(R.color.bg);
if(!isChecked){
}
} else {
System.out.println("false");
}
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text = (TextView) convertView.findViewById(R.id.label);
holder.text.setText(child.get(position).getName());
return convertView;
}
static class ViewHolder {
TextView text;
}
}
In My Assumption
ExpandListAdapter Class
In getChildView() method childPosition does not depends on what country flag is being clicked , Because childPosition here returns the position of the Grid view, not the flags under it
So, no need to pass childPosition in constructor of GridView ,since childPosition will always return 1
To get actual flag clicked position Use onClickListener inside your GridAdapter like:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
NetworkImageView i;
childPosition = position;
if (convertView == null) {
} else {
holder = (ViewHolder) convertView.getTag();
}
convertView.setOnclickListener(new OnClickListener{
#Override
onClick(View v){
isChecked=child.get(childPosition).isChecked();
if(!isChecked){
child.get(childPosition).setChecked(true);
}
else {
child.get(childPosition).setChecked(false);
}
});
No need to handle checked positions separately create two methods in your child class isChecked() and setChecked() to maintain check-uncheck state of flags.
Change color of selected or checked flag here
holder.text = (TextView) convertView.findViewById(R.id.label);
holder.text.setText(child.get(position).getName());
return convertView;
}
and remove your Check logic from ExpandListAdapter Class :
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
setClicked(groupPosition, childPosition);
System.out.println("position" + checkedPositions.get(groupPosition));
if (checkedPositions.get(groupPosition) != null) {
boolean isChecked = checkedPositions.get(groupPosition).get(childPosition);
if(!isChecked){
}
} else {
System.out.println("false");
}
}
});
You need to set an 'OnItemClickListener' to your gridAdapter, and overide the onItemClick method as following.
Note :- This will highlight the ImageView you click and if you happened to click another ImageView in the same GridView, that ImageView also will be highlighted! Like in a 'multiple selection'.
gridAdapter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ImageView selectedFlagImageView = (ImageView) view;
selectedFlagImageView.setBackgroundColor(Color.parseColor("#37a93400"));
}
});
This will color the background of the selected ImageView. Color code I've used in here is simply, more alpha and less RGBs.(I used Android Studio color chooser)
Following images will give you an idea about how it will look when giving a background color like this.
Without background color :
With background color :
I am developing a Music Player. All songs are placed in the ListView with a ImageButton. This button is playing and pause the songs. So I am using getview(). But when I am clicking on the ImageButton, the songs are playing and pausing, but the image of play/pause is not changing. My main issue as I think, is that, when I am clicking on the ImageButton it is not calling the getview(). So please help me.
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_ringtones);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ringtones);
mAdapter = new RingtonesMusicAdapter(this, R.layout.ringtones_row);
mListView.setAdapter(mAdapter);
}
public void invalidatePlayButtons(int position) {
for (int i = 0; i < mTrackData.size(); i++) {
if (i != position) {
try {
//mTrackData.get(i).getRowItem().mPlayButton.setImageResource(R.drawable.play);
if (MusicManager.getInstance().isPlaying(mTrackData.get(i))) {
MusicManager.getInstance().stop();
mTrackData.get(i).getRowItem().mProgressBar
.setProgress(0);
}
} catch (Exception ex) {
ex.printStackTrace();
}
} else
mTrackData.get(i).getRowItem().mPlayButton
.setImageResource(R.drawable.pause);
}
}
public void onPlayClick(View view) {
Object obj = view.getTag();
if (obj != null && obj.getClass() == RowItem.class) {
final RowItem rowItem = (RowItem) obj;
if(rowItem.mPosition != mChantIndex ){
if (!MusicManager.getInstance().isPlaying(rowItem)) {
invalidatePlayButtons(rowItem.mPosition);
MusicManager.getInstance().showProgressAnimation(rowItem.mProgressBar);
// rowItem.mPlayButton.setImageResource(R.drawable.pause);
if(rowItem.isPause){
//rowItem.mPlayButton.setImageResource(R.drawable.pause);
MusicManager.getInstance().setLengthTrack();
}else{
rowItem.mMusicListener = this;
MusicManager.getInstance().playDownloadedTrack(rowItem);
if(rowItem.mPosition == mProgressbarIndex) {
mProgressbarIndex = -1;
}
else {
mProgressbarIndex = rowItem.mPosition;
}
}
}else if(MusicManager.getInstance().isPlaying(rowItem)){
MusicManager.getInstance().pauseTrack(rowItem);
MusicManager.getInstance().getLengthTrack();
//rowItem.mPlayButton.setImageResource(R.drawable.play);
rowItem.isPause = true;
}
}
}else {
invalidatePlayButtons(-1);
}
//mAdapter.notifyDataSetChanged();
}
#Override
public void onRefreshData(Refreshable refreshable, int requestCode) {
if (requestCode == SoundCloudManager.BITMAP_DATA) {
mAdapter.notifyDataSetChanged();
}
class RingtonesMusicAdapter extends ArrayAdapter<LinearLayout>{
Context mContext;
int mResource;
public RingtonesMusicAdapter(Context context, int resource) {
super(context, resource);
mContext =context;
mResource = resource;
}
#Override
public int getCount() {
return mTrackData.size();
}
public LinearLayout getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout row;
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
row =(LinearLayout)inflater.inflate(mResource, parent, false);
RowItem rowItem = new RowItem(position);
mTrackData.get(position).setRowItem(rowItem);
rowItem.mTrack = mTrackData.get(position);
rowItem.setupRowForRingtone(row);
return row;
}
#Override
public boolean isEnabled(int position) {
return true;
}
}
Method rowItem.setupRowForRingtone(row) has the code for changing the play/pause the image.