I have 2 activities with listview and when I go to activity B and back to A and click, I get error:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131492961, class android.widget.ListView) with Adapter(class com.example.example.ItemListBaseAdapter)]
When I need to call notifyDataSetChanged()?
In my acticities or in ItemListBaseAdapter Class?
The code in my activities:
ArrayList<ItemDetails> image_details = GetSearchResults();
final ListView lv1 = (ListView) findViewById(R.id.list);
lv1.setAdapter(new ItemListBaseAdapter(getApplicationContext(), image_details));
lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Object o = lv1.getItemAtPosition(position);
}
});
private ArrayList<ItemDetails> GetSearchResults() {
ArrayList<ItemDetails> results = new ArrayList<ItemDetails>();
for(int i = 0;i<Code.size();i++) {
ItemDetails item_details = new ItemDetails();
item_details.setName(getString(R.string.newanswer));
item_details.setItemDescription(Book.get(i) + " - " + getString(R.string.page) + " " + Page.get(i) + " " + getString(R.string.exercise) + " " + Exercise.get(i) + "\n" + getString(R.string.clicktoshow));
item_details.setImageNumber(2000);
results.add(item_details);
}
return results;
}
The ItemListBaseAdapter Class:
public class ItemListBaseAdapter extends BaseAdapter {
private static ArrayList<ItemDetails> itemDetailsrrayList;
private LayoutInflater l_Inflater;
public ItemListBaseAdapter(Context context, ArrayList<ItemDetails> results) {
itemDetailsrrayList = results;
l_Inflater = LayoutInflater.from(context);
}
public int getCount() {
return itemDetailsrrayList.size();
}
public Object getItem(int position) {
return itemDetailsrrayList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = l_Inflater.inflate(R.layout.item_details_view, null);
holder = new ViewHolder();
holder.txt_itemName = (TextView) convertView.findViewById(R.id.name);
holder.txt_itemDescription = (TextView) convertView.findViewById(R.id.itemDescription);
holder.itemImage = (ImageView) convertView.findViewById(R.id.photo);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txt_itemName.setText(itemDetailsrrayList.get(position).getName());
holder.txt_itemDescription.setText(itemDetailsrrayList.get(position).getItemDescription());
if(itemDetailsrrayList.get(position).getImageNumber() == 1999) {
holder.itemImage.setImageResource(R.drawable.person);
}
else {
if(itemDetailsrrayList.get(position).getImageNumber() == 2000) {
holder.itemImage.setImageResource(R.drawable.icon);
}
else {
byte[] a = itemDetailsrrayList.get(position).getPicture();
Bitmap bmp = BitmapFactory
.decodeByteArray(
a, 0,
a.length);
holder.itemImage.setImageBitmap(bmp);
}
}
return convertView;
}
static class ViewHolder {
TextView txt_itemName;
TextView txt_itemDescription;
ImageView itemImage;
}}
Related
I am a French student, sorry for my mistakes.
I have to do a major project of 6 months to validate my studies. This project consists of creating an Android application.
My application consists of a listView with a custom adapter (TextView and CheckBox).
My problem is that I want to check a CheckBox that is not in the current view of my listView. For example if I want to check a checkbox at the bottom of the list and I am at the top of it (it is not visible on the screen). The checkbox check is not the right one, it ticks one randomly in the current view.
Picture ListView
Here is the view code:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) selectActivity.getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.station_list_item, null);
}
//Handle TextView and display string from your list
TextView textViewListNomStation = (TextView)view.findViewById(R.id.textViewListNomStation);
//Log.i(tag, "nom :" +infosStationsCapteurs.cInfosStationArrayList.get(position).getNomStation() );
textViewListNomStation.setText(infosStationsCapteurs.getcInfosStationArrayList().get(position).getNomStation() + " ID : " + infosStationsCapteurs.getcInfosStationArrayList().get(position).getIdStation());
TextView textViewListInfosStation = (TextView)view.findViewById(R.id.textViewListInfosStation);
String formatInfos = "Lat : " + infosStationsCapteurs.getcInfosStationArrayList().get(position).getPositionGPS().getLatitude() + " Lon : " + infosStationsCapteurs.getcInfosStationArrayList().get(position).getPositionGPS().getLongitude();
textViewListInfosStation.setText(formatInfos);
//Handle buttons and add onClickListeners
CheckBox checkBoxStation = (CheckBox) view.findViewById(R.id.checkBoxStation);
checkBoxTab[position] = checkBoxStation;
checkBoxTab[position].setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// Log.i(tag, "Bouton :" + buttonView.getId() + " Status " + isChecked);
if (isChecked == true)
{
mCheckedState[position]=true;
selectActivity.getTableauCapteurs().addHashSetstationChecked((cInfosStation)getItem(position));
selectActivity.getTableauCapteurs().createTable();
}
if (isChecked == false){
mCheckedState[position]=false;
selectActivity.getTableauCapteurs().deleteHashSetstationChecked((cInfosStation)getItem(position));
selectActivity.getTableauCapteurs().createTable();
}
}
});
checkBoxTab[position].setChecked(mCheckedState[position]);
return view;
}
Here is the code that allows me to check a checkbox in the listView
public void checkListStation(int id, boolean etat)
{
//Log.i(tag,"CheckListStation : NBR STATION : " + infosStationsCapteurs.getcInfosStationArrayList().size());
for (int i = 0;i<infosStationsCapteurs.getcInfosStationArrayList().size();i++)
{
//Log.i(tag, "CHECK " + infosStationsCapteurs.getcInfosStationArrayList().get(i).getNomStation() + " : "+name);
if (infosStationsCapteurs.getcInfosStationArrayList().get(i).getIdStation()==id)
{
mCheckedState[i]=etat;
if (checkBoxTab[i]!=null)
{
checkBoxTab[i].setChecked(etat);
Log.i(tag, "Checkbox : " + i + " : " + checkBoxTab[i].isChecked() + "taille : " + checkBoxTab.length);
}
}
}
this.notifyDataSetChanged();
}
Here is an image that shows the problem. If I want to check the one down it will check the top one instead:
Example
I hope I have been clear enough.
Thank you very much for your help.
Can you post the picture of what you want to do?It is not clear.
But what I think you want one listview which have multiple items and each item holds one checkbox.If it is then you can do it by using custom listview with adapter.
You can refer below caode
public class GeneratedOrderListAdapter extends BaseAdapter {
Context mContext;
ViewHolder holder;
Typeface tf_bold, tf_regular;
ArrayList<GenerateOrder> arrayListgeneratOrder;
public GeneratedOrderListAdapter(Context context, ArrayList<GenerateOrder> arrayListgeneratOrder) {
mContext = context;
this.arrayListgeneratOrder = new ArrayList<>();
this.arrayListgeneratOrder = arrayListgeneratOrder;
this.tf_bold = Typeface.createFromAsset(mContext.getAssets(), "opensans_semibold.ttf");
this.tf_regular = Typeface.createFromAsset(mContext.getAssets(), "opensans_regular.ttf");
}
#Override
public int getCount() {
return arrayListgeneratOrder.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
static class ViewHolder {
TextView mOrderNO;
TextView mCustomerName;
TextView mStatus;
TextView mTotalAmount;
TextView mtextOrderNO;
TextView mtextCustomerName;
TextView mtextStatus;
TextView mtextTotalAmount;
RelativeLayout relback;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
LayoutInflater mInflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (view == null) {
view = mInflater.inflate(R.layout.order_list, null);
holder = new ViewHolder();
holder.mtextStatus = (TextView) view.findViewById(R.id.txt_t_status);
holder.mtextOrderNO = (TextView) view.findViewById(R.id.txt_title_orderno);
holder.mtextCustomerName = (TextView) view.findViewById(R.id.txt_t_customer);
holder.mtextTotalAmount = (TextView) view.findViewById(R.id.txt_t_amount);
holder.mStatus = (TextView) view.findViewById(R.id.txt_status);
holder.mOrderNO = (TextView) view.findViewById(R.id.txt_orderno);
holder.mCustomerName = (TextView) view.findViewById(R.id.txt_customer);
holder.mTotalAmount = (TextView) view.findViewById(R.id.txt_amount);
holder.relback=(RelativeLayout)view.findViewById(R.id.rel_back);
// setTypeFace();
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
try {
holder.mStatus.setText(arrayListgeneratOrder.get(position).getOrderStatus());
holder.mTotalAmount.setText(arrayListgeneratOrder.get(position).getAmount());
holder.mCustomerName.setText(arrayListgeneratOrder.get(position).getCustomerName());
holder.mOrderNO.setText(arrayListgeneratOrder.get(position).getOrderNo());
if(position%2==0){
holder.relback.setBackgroundColor(Color.parseColor("#f4fff5"));
}else{
holder.relback.setBackgroundColor(Color.parseColor("#ffffff"));
}
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
private void setTypeFace() {
holder.mStatus.setTypeface(tf_regular);
holder.mTotalAmount.setTypeface(tf_regular);
holder.mCustomerName.setTypeface(tf_regular);
holder.mOrderNO.setTypeface(tf_regular);
holder.mtextStatus.setTypeface(tf_regular);
holder.mtextOrderNO.setTypeface(tf_regular);
holder.mtextCustomerName.setTypeface(tf_regular);
holder.mtextTotalAmount.setTypeface(tf_regular);
}
}
In your model class add CheckFlag paramter and initialize to zero
//Handle buttons and add onClickListeners
CheckBox checkBoxStation = (CheckBox) view.findViewById(R.id.checkBoxStation);
int check_flag=infosStationsCapteurs.getcInfosStationArrayList().get(position).getPositionGPS().getCheckFlag();
if(check_flag==1)
{
checkBoxStation.setChecked(true);
}
else
{
checkBoxStation.setChecked(false);
}
checkBoxStation.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//Log.i(tag, "Bouton :" + buttonView.getId() + " Status " + isChecked);
if (isChecked)
{
infosStationsCapteurs.getcInfosStationArrayList().get(position).getPositionGPS().setCheckFlag(1);
}
else{
{
infosStationsCapteurs.getcInfosStationArrayList().get(position).getPositionGPS().setCheckFlag(0);
}
notifyDataSetChanged();
}
});
Use the code below.
This is adater class
public class AttendanceAdapter extends BaseAdapter{
Context ctx;
LayoutInflater lInflater;
ArrayList<Student> objects;
public AttendanceAdapter(Context context, ArrayList<Student> students) {
ctx = context;
objects = students;
lInflater = (LayoutInflater) ctx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return objects.size();
}
#Override
public Object getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.atndnc_items, parent, false);
}
Student s = getStudent(position);
((TextView) view.findViewById(R.id.txtRollno)).setText(s.rollno);
((TextView) view.findViewById(R.id.txtName)).setText(s.fname+" "+s.mname+" "+s.lname);
final CheckBox cbAtnd = (CheckBox) view.findViewById(R.id.chckTick);
cbAtnd.setOnCheckedChangeListener(myCheckChangList);
cbAtnd.setTag(position);
cbAtnd.setChecked(s.chck);
return view;
}
Student getStudent(int position) {
return ((Student) getItem(position));
}
public ArrayList<Student> getBox() {
ArrayList<Student> box = new ArrayList<Student>();
for (Student s : objects) {
box.add(s);
}
return box;
}
CompoundButton.OnCheckedChangeListener myCheckChangList = new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
getStudent((Integer) buttonView.getTag()).chck = isChecked;
}
};}
Then create one object of your adater and call this method from your main activity.Here boxadater is the object of my Adapter class.
public void getValue(){
for (Student s :boxAdapter.getBox()) {
attendance.attendancelist.add(new Attendance( s.rollno,s.fname+" "+s.mname+" "+s.lname,s.chck));
}
}
I have two different card view in one layout. I need that The latest news is added to one card view, and the rest in another. For exapmle, on image
MyRecyclerAdapter code
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.CustomViewHolder> {
private List<FeedItem> feedItemList;
private Context mContext;
public MyRecyclerAdapter(Context context, List<FeedItem> feedItemList) {
this.feedItemList = feedItemList;
this.mContext = context;
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, null);
CustomViewHolder viewHolder = new CustomViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(CustomViewHolder customViewHolder, int i) {
FeedItem feedItem = feedItemList.get(i);
//Download image using picasso library
Picasso.with(mContext).load(feedItem.getThumbnail())
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(customViewHolder.imageView);
//Setting text view title
customViewHolder.textView.setText(Html.fromHtml(feedItem.getTitle()));
View.OnClickListener clickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
CustomViewHolder holder = (CustomViewHolder) view.getTag();
int position = holder.getPosition();
FeedItem feedItem = feedItemList.get(position);
Toast.makeText(mContext, feedItem.getTitle(), Toast.LENGTH_SHORT).show();
}
};
//Handle click event on both title and image click
customViewHolder.textView.setOnClickListener(clickListener);
customViewHolder.imageView.setOnClickListener(clickListener);
customViewHolder.textView.setTag(customViewHolder);
customViewHolder.imageView.setTag(customViewHolder);
}
#Override
public int getItemCount() {
return (null != feedItemList ? feedItemList.size() : 0);
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
protected ImageView imageView;
protected TextView textView;
public CustomViewHolder(View view) {
super(view);
this.imageView = (ImageView) view.findViewById(R.id.thumbnail);
this.textView = (TextView) view.findViewById(R.id.title);
}
}
}
The approach I would use if I were in you, to accomplish what you posted in the picture is to override getItemViewType and have two different types of ViewHolder, once for the header, the one with the big image and the other adapter for the small rows. onBindViewHolder gets the type as parameter. In your case is int i.
I write a quickdemo like this:
private class MyCustomAdapter extends BaseAdapter {
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;
private ArrayList mData = new ArrayList();
private LayoutInflater mInflater;
private TreeSet mSeparatorSet = new TreeSet();
public MyCustomAdapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addItem(String item) {
mData.add(item);
notifyDataSetChanged();
}
public void addSeparator(String item) {
mData.add(item);
mSeparatorSet.add(mData.size() - 1);
notifyDataSetChanged();
}
#Override
public int getItemViewType(int position) {
return mSeparatorSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}
#Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int position) {
return mData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
System.out.println("getView " + position + " " + convertView + "type " + type);
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.item1, null);
holder.textView = (TextView) convertView.findViewById(R.id.text_view);
break;
case TYPE_SEPARATOR:
convertView = mInflater.inflate(R.layout.item2, null);
holder.textView = (TextView) convertView.findViewById(R.id.textSeparator);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(mData.get(position) + "");
return convertView;
}
}
public static class ViewHolder {
public TextView textView;
}
or if you want to use header and footer, create headerView layout:
View header = (View) getLayoutInflater().inflate(R.layout.headerView,null);
listView.addHeaderView(header);
I am calling three JSONRequests with Volley and this method is called at every response of the request. This method only is executed when all three responses are ready. But when I try to update the expandable list it fails to display on the screen. Could anyone see if I am doing something wrong?
private void updateWhenReady(){
System.out.println(validCurrent+ " " + validDaily + " " + validHourly );
if(validCurrent && validDaily && validHourly)
{
System.out.println("in");
for (WeatherCondition wc: dailyResponseList)
{
ArrayList<WeatherCondition> tempList = new ArrayList<>();
for(WeatherCondition w: hourlyResponseList)
{
if(w.getDate().equalsIgnoreCase(wc.getDate()))
{
tempList.add(w);
}
}
weatherList.put(wc,tempList);
}
for (WeatherCondition weatherCondition: weatherList.keySet())
{
System.out.println(" + " + weatherCondition.getDate());
}
weatherList = dbHelper.getWeatherConditionsHashMap();
hourlyList = new ArrayList<WeatherCondition>(weatherList.keySet());
adapter = new WeatherSearchListAdapter(getActivity().getApplicationContext(), weatherList, hourlyList);
expList.setAdapter(adapter);
adapter.notifyDataSetChanged();
System.out.println(validCurrent + " " + validDaily + " " + validHourly);
validCurrent = false;
validDaily = false;
validHourly = false;
}
}
and the following is the explist adapter
public class WeatherSearchListAdapter extends BaseExpandableListAdapter {
private Context ctx;
private HashMap<WeatherCondition, List<WeatherCondition>> weatherList;
private List<WeatherCondition> list;
public WeatherSearchListAdapter(Context ctx, HashMap<WeatherCondition, List<WeatherCondition>> parentList, List<WeatherCondition> list){
this.weatherList = parentList;
this.list = list;
this.ctx = ctx;
};
#Override
public int getGroupCount() {
return list.size();
}
#Override
public int getChildrenCount(int groupPosition) {
return weatherList.get(list.get(groupPosition)).size();
}
#Override
public Object getGroup(int groupPosition) {
return list.get(groupPosition);
}
#Override
public Object getChild(int parent, int child) {
return weatherList.get(list.get(parent)).get(child);
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public long getChildId(int parent, int child) {
return child;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
WeatherCondition groupWeatherCondition = (WeatherCondition) getGroup(groupPosition);
if(convertView == null)
{
LayoutInflater inflator = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflator.inflate(R.layout.fragment_daily_list_parent, parent, false);
}
ImageView weatherIconIdIV = (ImageView) convertView.findViewById(R.id.weatherIconIV);
ImageView windIconIdIV = (ImageView) convertView.findViewById(R.id.windDirectionIV);
TextView humidityTV = (TextView) convertView.findViewById(R.id.humitityListText);
TextView rainTV = (TextView) convertView.findViewById(R.id.rainListText);
TextView windDirectionTV = (TextView) convertView.findViewById(R.id.windDirectionText);
TextView windSpeedTV = (TextView) convertView.findViewById(R.id.windSpeedText);
TextView maxTempTV = (TextView) convertView.findViewById(R.id.maxTempListText);
TextView minTempTV = (TextView) convertView.findViewById(R.id.minTempListText);
TextView dateTV = (TextView) convertView.findViewById(R.id.dateListText);
String name = groupWeatherCondition.getWeatherIconId();
int weatherIconId = ctx.getResources().getIdentifier(name, "drawable", ctx.getPackageName());
weatherIconIdIV.setImageResource(weatherIconId);
String name1 = groupWeatherCondition.getWind().getWindIconId();
int windIconId = ctx.getResources().getIdentifier(name1, "drawable", ctx.getPackageName());
windIconIdIV.setImageResource(windIconId);
humidityTV.setText(groupWeatherCondition.getHumidity());
rainTV.setText(groupWeatherCondition.getRain());
windDirectionTV.setText(groupWeatherCondition.getWind().getWindDirection());
windSpeedTV.setText(groupWeatherCondition.getWind().getSpeed());
maxTempTV.setText(groupWeatherCondition.getMaxTemp());
minTempTV.setText(groupWeatherCondition.getMinTemp());
dateTV.setText(groupWeatherCondition.getDate());
convertView.setBackgroundColor(Color.parseColor("#5E5E5E"));
return convertView;
}
#Override
public View getChildView(int parent, int child, boolean isLastChild, View convertView, ViewGroup parentView) {
WeatherCondition childWeatherCondition = (WeatherCondition) getChild(parent, child);
if(convertView == null)
{
LayoutInflater inflator = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflator.inflate(R.layout.fragment_daily_list_parent, parentView, false);
}
ImageView weatherIconIdIV = (ImageView) convertView.findViewById(R.id.weatherIconIV);
ImageView windIconIdIV = (ImageView) convertView.findViewById(R.id.windDirectionIV);
TextView humidityTV = (TextView) convertView.findViewById(R.id.humitityListText);
TextView rainTV = (TextView) convertView.findViewById(R.id.rainListText);
TextView windDirectionTV = (TextView) convertView.findViewById(R.id.windDirectionText);
TextView windSpeedTV = (TextView) convertView.findViewById(R.id.windSpeedText);
TextView maxTempTV = (TextView) convertView.findViewById(R.id.maxTempListText);
TextView minTempTV = (TextView) convertView.findViewById(R.id.minTempListText);
TextView dateTV = (TextView) convertView.findViewById(R.id.dateListText);
String name = childWeatherCondition.getWeatherIconId();
int weatherIconId = ctx.getResources().getIdentifier(name, "drawable", ctx.getPackageName());
weatherIconIdIV.setImageResource(weatherIconId);
String name1 = childWeatherCondition.getWind().getWindIconId();
int windIconId = ctx.getResources().getIdentifier(name1, "drawable", ctx.getPackageName());
windIconIdIV.setImageResource(windIconId);
humidityTV.setText(childWeatherCondition.getHumidity());
rainTV.setText(childWeatherCondition.getRain());
windDirectionTV.setText(childWeatherCondition.getWind().getWindDirection());
windSpeedTV.setText(childWeatherCondition.getWind().getSpeed());
maxTempTV.setText(childWeatherCondition.getMaxTemp());
minTempTV.setText(childWeatherCondition.getMinTemp());
dateTV.setText(childWeatherCondition.getDate());
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
Do the variable initializations before the logic starts -
private void updateWhenReady(){
System.out.println(validCurrent+ " " + validDaily + " " + validHourly );
weatherList = dbHelper.getWeatherConditionsHashMap();
hourlyList = new ArrayList<WeatherCondition>(weatherList.keySet());
adapter = new WeatherSearchListAdapter(getActivity().getApplicationContext(), weatherList, hourlyList);
System.out.println(validCurrent + " " + validDaily + " " + validHourly);
if(validCurrent && validDaily && validHourly)
{
System.out.println("in");
for (WeatherCondition wc: dailyResponseList)
{
ArrayList<WeatherCondition> tempList = new ArrayList<>();
for(WeatherCondition w: hourlyResponseList)
{
if(w.getDate().equalsIgnoreCase(wc.getDate()))
{
tempList.add(w);
}
}
weatherList.put(wc,tempList);
}
for (WeatherCondition weatherCondition: weatherList.keySet())
{
System.out.println(" + " + weatherCondition.getDate());
}
//Do you need to reset these? What if only two of the three were true?
validCurrent = false;
validDaily = false;
validHourly = false;
}
}
expList.setAdapter(adapter);
/* If you are setting adapter every time *updateWhenReady* is invoked, no need to notifyDataSetChanged, because its a new adapter and layout will be drawn fresh */
//adapter.notifyDataSetChanged();
}
In getChildView
inflate using fragment_daily_list_parent
copy-past error?
I have my Custom Adapter because I have a ImageButton and want to set the onClickListener.
The problem is when I click for example the element in the position 0 it returns the element in position 3; I do not understand why..
This is the Custom Adapter:
public class CustomAdapter extends BaseAdapter {
private final Activity context;
private LayoutInflater mInflater;
private ArrayList<HashMap<String, Object>> mlist;
private String mNome;
private String mCognome;
private String mTitolo;
private String mInfo;
ViewHolder viewHolder;
View view;
ArrayList<Integer> map = new ArrayList<>();
HashMap<String, Object> e;
public CustomAdapter(Activity context,ArrayList<HashMap<String, Object>> mlist){
this.context = context;
this.mlist=mlist;
mInflater = context.getLayoutInflater();
}
public class ViewHolder {
public ImageButton mImageButton;
public TextView mTitleView;
public TextView mNomeView;
public TextView mCognomeView;
public TextView mInfoView;
}
#Override
public int getCount() {
return mlist.size();
}
#Override
public Object getItem(int position) {
Log.d("POSITION GET",Integer.toString(position));
if (mlist != null && position >= 0 && position < getCount()) {
Log.d("POSITION GET",Integer.toString(position));
return mlist.get(position);
}
return null;
}
#Override
public long getItemId(int position) {
if (mlist != null && position >= 0 && position < getCount()) {
return Integer.parseInt((String)mlist.get(position).get("id"));
}
return position;
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
view = convertView;
e = (HashMap<String, Object>) getItem(position);
if (view == null) {
view = mInflater.inflate(R.layout.item_list_avvisi, parent, false);
viewHolder = new ViewHolder();
viewHolder.mImageButton = (ImageButton) view.findViewById(R.id.imageButton);
viewHolder.mCognomeView = (TextView) view.findViewById(R.id.cognome);
viewHolder.mNomeView = (TextView) view.findViewById(R.id.nome);
viewHolder.mTitleView = (TextView) view.findViewById(R.id.titolo);
viewHolder.mInfoView = (TextView) view.findViewById(R.id.info);
viewHolder.mImageButton.setClickable(true);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.mImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String nome = e.get("Nome").toString();
Log.d("TAG", nome);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TEXT, (String) "Avviso Scuola: " + nome + " " +
mCognome + "\n" +
mTitolo + "\n" +
mInfo
);
shareIntent.setType("text/plain");
context.startActivity(shareIntent);
}
});
viewHolder.mCognomeView.setText(e.get("Cognome").toString());
viewHolder.mNomeView.setText(e.get("Nome").toString());
viewHolder.mTitleView.setText(e.get("Titolo").toString());
viewHolder.mInfoView.setText(e.get("Info").toString());
return view;
}
And in the fragment i have:
private ArrayList<HashMap<String, Object>> mlist = new ArrayList<HashMap<String, Object>>();
...
for (int i = 1; i < array.length(); i++) {
HashMap<String, Object> map = new HashMap<String, Object>();
Gson gson = new Gson();
Avv mAvv = gson.fromJson(String.valueOf(array.getJSONObject(i)), Avv.class);
map.put("id", String.valueOf(i));
map.put("Name", mAvv.getNome());
map.put("Surname", mAvv.getCognome());
map.put("Title", mAvv.getTitolo());
map.put("Info", mAvv.getTesto());
mlist.add(map);
}
...
CustomAdapter mAdapter = new CustomAdapter(getActivity(),mlist);
list.setAdapter(mAdapter);
shareIntent.putExtra(Intent.EXTRA_TEXT, (String) "Avviso " + tx.getText().toString());
You are using data used from the Views that are recycled. Don't do that, ever. Instead get that data from the ArrayList
mlist.get(postion)....
You have to add the final declaration to the position in order for it to be accessible inside the onClick method
public View getView(final int position, View convertView, ViewGroup parent) {
I am trying to create something like this: https://i.stack.imgur.com/l8ZOc.png
However, i ran into a problem. When i create the list with my adapter, it is supposed to be a list of 8 items. However, it just shows the first 4 of these items in a random order two times. Do you see what is wrong with my code?
public class MyActivity extends Activity{
String headers[];
String image_urls[];
List<MyMenuItem> menuItems;
ListView mylistview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
menuItems = new ArrayList<MyMenuItem>();
headers = getResources().getStringArray(R.array.header_names);
image_urls = getResources().getStringArray(R.array.image_urls);
for (int i = 0; i < headers.length; i++) {
MyMenuItem item = new MyMenuItem(headers[i], image_urls[i]);
menuItems.add(item);
}
mylistview = (ListView) findViewById(R.id.list);
MenuAdapter adapter = new MenuAdapter(this, menuItems);
mylistview.setAdapter(adapter);
mylistview.setOnItemClickListener(this);
}
public class MyMenuItem {
private String item_header;
private String item_image_url;
public MyMenuItem(String item_header, String item_image_url){
this.item_header=item_header;
this.item_image_url=item_image_url;
}
public String getItem_header(){
return item_header;
}
public void setItem_header(String item_header){
this.item_header=item_header;
}
public String getItem_image_url(){
return item_image_url;
}
public void setItem_image_url(String item_image_url){
this.item_image_url=item_image_url;
}
}
public class MenuAdapter extends BaseAdapter{
Context context;
List<MyMenuItem> menuItems;
MenuAdapter(Context context, List<MyMenuItem> rowItems) {
this.context = context;
this.menuItems = rowItems;
}
#Override
public int getCount() {
return menuItems.size();
}
#Override
public Object getItem(int position) {
return menuItems.get(position);
}
#Override
public long getItemId(int position) {
return menuItems.indexOf(getItem(position));
}
private class ViewHolder {
ImageView ivMenu;
TextView tvMenuHeader;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.menu_item, null);
holder = new ViewHolder();
holder.tvMenuHeader = (TextView) convertView.findViewById(R.id.tvMenuHeader);
holder.ivMenu = (ImageView) convertView.findViewById(R.id.ivMenuItem);
MyMenuItem row_pos = menuItems.get(position);
Picasso.with(context)
.load(row_pos.getItem_image_url())
.placeholder(R.drawable.empty)
.error(R.drawable.error)
.into(holder.ivMenu);
holder.tvMenuHeader.setText(row_pos.getItem_header());
Log.e("Test", "headers:" + row_pos.getItem_header());
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
}
You are setting the data only when the convertView is null.So when it is not null,list items are inflated with data of previous list items. getView should be something like this
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.menu_item, null);
holder = new ViewHolder();
holder.tvMenuHeader = (TextView) convertView.findViewById(R.id.tvMenuHeader);
holder.ivMenu = (ImageView) convertView.findViewById(R.id.ivMenuItem);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
MyMenuItem row_pos = menuItems.get(position);
Picasso.with(context)
.load(row_pos.getItem_image_url())
.placeholder(R.drawable.empty)
.error(R.drawable.error)
.into(holder.ivMenu);
holder.tvMenuHeader.setText(row_pos.getItem_header());
Log.e("Test", "headers:" + row_pos.getItem_header());
return convertView;
}
I think this is the solution
else {
holder = (ViewHolder) convertView.getTag();
holder.tvMenuHeader.setText(row_pos.getItem_header());
}
I also encountered this problem earlier and this one works for me.