user6720111 user6720111 - 3 months ago 15
Android Question

Update ActionBar from Adapter

I have a basket icon with count notification on it in actionbar for showing number of goods in shopping basket. also I have a custom view containing a button for add goods to shopping basket. I want that when I click on button (in custom view) notification count on basket icon increases. I use this function in main activity to update notification count but notification does not update.

public static void updateCountBasket(final int number , int id , View view ,Context context) {

if (view.findViewById(id) == null)
return;
TextView t = (TextView)view.findViewById(id);
String dd = t.getText().toString();
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
if (number == 0)
t.setVisibility(View.INVISIBLE);
else {
t.setVisibility(View.VISIBLE);
t.setText(Integer.toString(number));
}
}
});
}


but when I use non static of that function in main activity with simple button on click, it works fine. but I can't call non static function in base adapter too :( . I checked line by line of the function in static mode all ids are right and it set text too but nothing change or get error!!. please help me to change textview as notification of basket in menubar from base adapter when button in custom view clicks. thanks
I have this base adapter for my custom view list:

public class Goods_ImageAdapter extends BaseAdapter {
private Context context;
private final JSONArray Goods;
private Bagde bagde;

public Goods_ImageAdapter(Context context , JSONArray Goods) {
this.context = context;
this.Goods = Goods;
bagde = Bagde.getInstance();
}

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

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

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

public static String doubleToStringNoDecimal(double d) {
DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);;
formatter .applyPattern("#,###");
return formatter.format(d);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View gridView;
final View bagde_c;
if (convertView == null) {
gridView = new View(context);
gridView = inflater.inflate(R.layout.goodsitem, null);
bagde_c = inflater.inflate(R.layout.badge_counter, null);

try {
TextView goods_textview_Name = (TextView) gridView.findViewById(R.id.goods_textview_Name);
goods_textview_Name.setText(Goods.getJSONObject(position).getString("Name"));

TextView goods_textview_Price = (TextView) gridView.findViewById(R.id.goods_textview_Price);
goods_textview_Price.setText(Goods.getJSONObject(position).getString("Price"));
} catch (JSONException e) {
e.printStackTrace();
}

try {
ImageView goods_imageview = (ImageView) gridView.findViewById(R.id.goods_imageview);
new ImageDownloader(goods_imageview).execute("http://IP/" + Goods.getJSONObject(position).getString("ImageFileName"));
} catch (JSONException e) {
e.printStackTrace();
}

final TextView goods_textview_bagdecounter = (TextView) gridView.findViewById(R.id.goods_textview_bagdecounter);
ImageView goods_buy_plus = (ImageView) gridView.findViewById(R.id.goods_buy_button_plus);
try {
goods_buy_plus.setTag(Goods.getJSONObject(position));
} catch (JSONException e) {
e.printStackTrace();
}
goods_buy_plus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
String bagde_counter_text = goods_textview_bagdecounter.getText().toString();
goods_textview_bagdecounter.setText(String.valueOf(Integer.parseInt(bagde_counter_text) + 1));
}
});
com.???.????.Goods_Activity.updateCountBasket(a number for example,R.id.notif,inflater2.inflate(R.layout.badge_counter, null),context);
}
});

ImageView goods_buy_minus = (ImageView) gridView.findViewById(R.id.goods_buy_button_minus);
try {
goods_buy_minus.setTag(Goods.getJSONObject(position));
} catch (JSONException e) {
e.printStackTrace();
}
goods_buy_minus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
String bagde_counter_text = goods_textview_bagdecounter.getText().toString();
if(Integer.parseInt(bagde_counter_text)> 0)
goods_textview_bagdecounter.setText(String.valueOf(Integer.parseInt(bagde_counter_text) - 1));
}
});
}
});
} else {
gridView = (View) convertView;
}

return gridView;
}


}

this is (basket with notification on action bar) badge_counter.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@android:style/Widget.ActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">

<RelativeLayout
android:id="@+id/badge_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<RelativeLayout
android:id="@+id/relative_layout_item_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<Button
android:id="@+id/button"
android:layout_width="40dip"
android:layout_height="40dip"
android:background="@drawable/download" />

<TextView
android:id="@+id/notif"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="@android:drawable/ic_notification_overlay"
android:text="33"
android:textColor="#FFA"
android:textSize="12sp"
android:textStyle="bold" />

</RelativeLayout>
</RelativeLayout>
</RelativeLayout>

Answer

You can achieve this by using interface.

Add an interface in Adapter class

public interface AdapterCallBack
{
    public void onChangeBadgeCount();
}

And in constructor, pass a reference to this interface.

public Goods_ImageAdapter(Context context ,  JSONArray Goods, AdapterCallBack adapterCallback) 
{
    this.context = context;
    this.Goods = Goods;
    this.adapterCallback = adapterCallback;
    bagde = Bagde.getInstance();
}

And whenever you want to set badge count in ActionBar, just call adapterCallback.onChangeBadgeCount().

And implement this interface in MainActivity.

public class MainActivity implements Goods_ImageAdapter.AdapterCallBack
{
    ... some code

    When your are initializing adapter, just pass this as a last parameter.
    Example:
    adapter = new Goods_ImageAdapter(this, Goods /* Json data */, this);
    ... 


    @override
    public void onChangeBadgeCount()
    {
        // Change your badge count here
    }
}
Comments