0

I have a listView that is supposed to accept a shared message and image where the image is placed within the ImageView. This feature works for just the first message, but once an image is shared, each message received after that initial one becomes a copy of that same image even though the blank image placeholder was already set, which is just a one pixel black png: holder.sharedSpecial.setImageResource(R.drawable.image_share_empty_holder);

An example is below:

enter image description here

The green textbox is the recipient. They have recieved a shared image from the yellow textbox. The yellow textbox then simply sends a normal message and I have set another image as a placeholder for normal messages: holder.sharedSpecial.setImageResource(R.drawable.image_share_empty_holder);

The same previously shared image takes precedence. I have used notifyDataSetChanged() so as to allow for the updating the adapter so that it would recognize not to use the same image, but to no avail.

How can I reformulate this class so that the image shared is only displayed with the proper message and not copied into each subsequent message?

The ArrayAdapter class:

public class DiscussArrayAdapter extends ArrayAdapter<OneComment> {

    class ViewHolder {
        TextView countryName;
        ImageView sharedSpecial;
        LinearLayout wrapper;
    }

    private TextView countryName;
    private ImageView sharedSpecial;

    private MapView locationMap;
    private GoogleMap map;

    private List<OneComment> countries = new ArrayList<OneComment>();
    private LinearLayout wrapper;

    private JSONObject resultObject;
    private JSONObject imageObject;

    String getSharedSpecialURL = null;
    String getSharedSpecialWithLocationURL = null;

    String specialsActionURL = "http://" + Global.getIpAddress()
            + ":3000/getSharedSpecial/";

    String specialsLocationActionURL = "http://" + Global.getIpAddress()
            + ":3000/getSharedSpecialWithLocation/";

    String JSON = ".json";

    @Override
    public void add(OneComment object) {
        countries.add(object);
        super.add(object);
    }

    public DiscussArrayAdapter(Context context, int textViewResourceId) {
        super(context, textViewResourceId);
    }

    public int getCount() {
        return this.countries.size();
    }

    private OneComment comment = null;

    public OneComment getItem(int index) {
        return this.countries.get(index);
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;

        View row = convertView;
        if (row == null) {
            LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.message_list_item, parent, false);

            holder = new ViewHolder();
            holder.wrapper = (LinearLayout) row.findViewById(R.id.wrapper);
            holder.countryName = (TextView) row.findViewById(R.id.comment);
            holder.sharedSpecial = (ImageView) row.findViewById(R.id.sharedSpecial);

            // Store the ViewHolder as a tag.
            row.setTag(holder);

        } else {
            holder = (ViewHolder) row.getTag();
        }

        Log.v("COMMENTING","Comment is " + countries.get(position).comment);

        //OneComment comment = getItem(position);
        holder.countryName.setText(countries.get(position).comment);

        // Initiating Volley
        final RequestQueue requestQueue = VolleySingleton.getsInstance().getRequestQueue();

        // Check if message has campaign or campaign/location attached
        if (countries.get(position).campaign_id == "0" && countries.get(position).location_id == "0") {

            holder.sharedSpecial.setImageResource(R.drawable.image_share_empty_holder);

            Log.v("TESTING", "It is working");

        } else if (countries.get(position).campaign_id != "0" && countries.get(position).location_id != "0") {

            // If both were shared
            getSharedSpecialWithLocationURL = specialsLocationActionURL + countries.get(position).campaign_id + "/" + countries.get(position).location_id + JSON;

            // Test Campaign id = 41
            //      Location id = 104

            // GET JSON data and parse
            JsonObjectRequest getCampaignLocationData = new JsonObjectRequest(Request.Method.GET, getSharedSpecialWithLocationURL, null,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {

                            // Parse the JSON:
                            try {
                                resultObject = response.getJSONObject("shared");

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                            // Get and set image
                            Picasso.with(getContext()).load("http://" + Global.getIpAddress() + ":3000" + adImageURL).into(holder.sharedSpecial);

                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            Log.d("Error.Response", error.toString());
                        }
                    }
            );

            requestQueue.add(getCampaignLocationData);

        } else if (countries.get(position).campaign_id != "0" && countries.get(position).location_id == "0") {

            // Just the campaign is shared
            getSharedSpecialURL = specialsActionURL + countries.get(position).campaign_id + JSON;

            // Test Campaign id = 41

            // GET JSON data and parse

            JsonObjectRequest getCampaignData = new JsonObjectRequest(Request.Method.GET, getSharedSpecialURL, null,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {

                            // Parse the JSON:
                            try {
                                resultObject = response.getJSONObject("shared");

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                            // Get and set image
                            Picasso.with(getContext()).load("http://" + Global.getIpAddress() + ":3000" + adImageURL).into(holder.sharedSpecial);

                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            Log.d("Error.Response", error.toString());
                        }
                    }
            );

            requestQueue.add(getCampaignData);

            // Location set to empty
        }

        // If left is true, then yellow, if not then set to green bubble
        holder.countryName.setBackgroundResource(countries.get(position).left ? R.drawable.bubble_yellow : R.drawable.bubble_green);
        holder.wrapper.setGravity(countries.get(position).left ? Gravity.LEFT : Gravity.RIGHT);

        return row;
    }

}

The messaging class that sends normal messages only but can receive image messages and set to the adapter:

public class GroupMessaging extends Activity {

    private static final int MESSAGE_CANNOT_BE_SENT = 0;
    public String username;
    public String groupname;

    private Button sendMessageButton;
    private Manager imService;
    private InfoOfGroup group = new InfoOfGroup();
    private InfoOfGroupMessage groupMsg = new InfoOfGroupMessage();
    private StorageManipulater localstoragehandler;
    private Cursor dbCursor;

    private com.example.feastapp.ChatBoxUi.DiscussArrayAdapter adapter;
    private ListView lv;
    private EditText editText1;

    private ServiceConnection mConnection = new ServiceConnection() {

        public void onServiceConnected(ComponentName className, IBinder service) {
            imService = ((MessagingService.IMBinder) service).getService();
        }

        public void onServiceDisconnected(ComponentName className) {
            imService = null;
            Toast.makeText(GroupMessaging.this, R.string.local_service_stopped,
                    Toast.LENGTH_SHORT).show();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.message_activity);

        lv = (ListView) findViewById(R.id.listView1);

        adapter = new DiscussArrayAdapter(getApplicationContext(), R.layout.message_list_item);

        lv.setAdapter(adapter);

        editText1 = (EditText) findViewById(R.id.editText1);

        sendMessageButton = (Button) findViewById(R.id.sendMessageButton);

        Bundle extras = this.getIntent().getExtras();

        group.userName = extras.getString(InfoOfGroupMessage.FROM_USER);
        group.groupName = extras.getString(InfoOfGroup.GROUPNAME);
        group.groupId = extras.getString(InfoOfGroup.GROUPID);
        String msg = extras.getString(InfoOfGroupMessage.GROUP_MESSAGE_TEXT);

        setTitle("Group: " + group.groupName);

        // Retrieve the information
        localstoragehandler = new StorageManipulater(this);
        dbCursor = localstoragehandler.groupGet(group.groupName);


        if (dbCursor.getCount() > 0) {
            // Probably where the magic happens, and keeps pulling the same
            // thing
            int noOfScorer = 0;
            dbCursor.moveToFirst();

            while ((!dbCursor.isAfterLast())
                    && noOfScorer < dbCursor.getCount()) {
                noOfScorer++;

            }
        }
        localstoragehandler.close();


        if (msg != null) {
            // Then friends username and message, not equal to null, recieved
            adapter.add(new OneComment(true, group.groupId + ": " + msg, "0", "0"));
            adapter.notifyDataSetChanged();

            ((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
                    .cancel((group.groupId + msg).hashCode());

        }

        // The send button
        sendMessageButton.setOnClickListener(new OnClickListener() {
            CharSequence message;
            Handler handler = new Handler();

            public void onClick(View arg0) {

                message = editText1.getText();
                if (message.length() > 0) {

                    // When general texting, the campaign and location will always be "0"
                    // Only through specials sharing is the user permitted to change the campaign and location to another value
                    adapter.add(new OneComment(false, imService.getUsername() + ": " + message.toString(), "0", "0"));
                    adapter.notifyDataSetChanged();

                    localstoragehandler.groupInsert(imService.getUsername(), group.groupName,
                            group.groupId, message.toString(), "0", "0");

                    // as msg sent, will blank out the text box so can write in
                    // again

                    editText1.setText("");
                    Thread thread = new Thread() {
                        public void run() {
                            try {

                                // JUST PUTTING "0" AS A PLACEHOLDER FOR CAMPAIGN AND LOCATION
                                // IN FUTURE WILL ACTUALLY ALLOW USER TO SHARE CAMPAIGNS
                                if (imService.sendGroupMessage(group.groupId,
                                        group.groupName, message.toString(), "0", "0") == null) {

                                    handler.post(new Runnable() {

                                        public void run() {

                                            Toast.makeText(
                                                    getApplicationContext(),
                                                    R.string.message_cannot_be_sent,
                                                    Toast.LENGTH_LONG).show();

                                            // showDialog(MESSAGE_CANNOT_BE_SENT);
                                        }

                                    });
                                }
                            } catch (UnsupportedEncodingException e) {
                                Toast.makeText(getApplicationContext(),
                                        R.string.message_cannot_be_sent,
                                        Toast.LENGTH_LONG).show();

                                e.printStackTrace();
                            }
                        }
                    };
                    thread.start();

                }

            }
        });

    }

    @Override
    protected Dialog onCreateDialog(int id) {
        int message = -1;
        switch (id) {
            case MESSAGE_CANNOT_BE_SENT:
                message = R.string.message_cannot_be_sent;
                break;
        }

        if (message == -1) {
            return null;
        } else {
            return new AlertDialog.Builder(GroupMessaging.this)
                    .setMessage(message)
                    .setPositiveButton(R.string.OK,
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                                    int whichButton) {
                                    /* User clicked OK so do some stuff */
                                }
                            }).create();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(groupMessageReceiver);
        unbindService(mConnection);

        ControllerOfGroup.setActiveGroup(null);

    }

    @Override
    protected void onResume() {
        super.onResume();
        bindService(new Intent(GroupMessaging.this, MessagingService.class),
                mConnection, Context.BIND_AUTO_CREATE);

        IntentFilter i = new IntentFilter();
        i.addAction(MessagingService.TAKE_GROUP_MESSAGE);

        registerReceiver(groupMessageReceiver, i);

        ControllerOfGroup.setActiveGroup(group.groupName);

    }

    // For receiving messages form other users...
    public class GroupMessageReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle extra = intent.getExtras();

            //Log.i("GroupMessaging Receiver ", "received group message");

            String username = extra.getString(InfoOfGroupMessage.FROM_USER);
            String groupRId = extra.getString(InfoOfGroupMessage.TO_GROUP_ID);
            String message = extra
                    .getString(InfoOfGroupMessage.GROUP_MESSAGE_TEXT);

            // NEED TO PLACE INTO THE MESSAGE VIEW!!
            String received_campaign_id = extra.getString(InfoOfGroupMessage.CAMPAIGN_SHARED);
            String received_location_id = extra.getString(InfoOfGroupMessage.LOCATION_SHARED);

            // NEED TO INTEGRATE THIS INTO LOGIC ABOVE, SO IT MAKES SENSE
            if (username != null && message != null) {
                if (group.groupId.equals(groupRId)) {

                    adapter.add(new OneComment(true, username + ": " + message, received_campaign_id, received_location_id));

                    localstoragehandler
                            .groupInsert(username, groupname, groupRId, message, received_campaign_id, received_location_id);

                    Toast.makeText(getApplicationContext(), "received_campaign: " + received_campaign_id +
                            " received_location:" + received_location_id, Toast.LENGTH_LONG).show();

                    received_campaign_id = "0";
                    received_location_id = "0";

                } else {
                    if (message.length() > 15) {
                        message = message.substring(0, 15);
                    }
                    Toast.makeText(GroupMessaging.this,
                            username + " says '" + message + "'",
                            Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    ;

    // Build receiver object to accept messages
    public GroupMessageReceiver groupMessageReceiver = new GroupMessageReceiver();

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (localstoragehandler != null) {
            localstoragehandler.close();
        }
        if (dbCursor != null) {
            dbCursor.close();
        }
    }

}
Sauron
  • 6,399
  • 14
  • 71
  • 136
  • 1
    Probably issue caused by `if (countries.get(position).campaign_id == "0" && countries.get(position).location_id == "0")` line so change it as: `if (countries.get(position).campaign_id.equals("0") && countries.get(position).location_id.equals("0"))` – ρяσѕρєя K Feb 24 '15 at 04:56
  • Why would they line cause repetition of images? – Sauron Feb 24 '15 at 05:22
  • @Sauron Refer to this [SO answer](http://stackoverflow.com/a/513839). It explains why you should use `.equals` to compare strings and not `==`. – iRuth Feb 24 '15 at 05:51
  • ...so it's basally saying, string type == string type, so all my if/else if statements will all be true, going one into the next... – Sauron Feb 24 '15 at 22:09

1 Answers1

0

I have gone through your code and this is common problem with listview that images starts repeating itself. In your case I think you have assigned image to Imageview every if and else if condition but if none of the condition satisfy it uses the previous image.

I would suggest to debug the getview method and put break points on the setImageResource. I use volley for these image loading and it has a method called defaultImage so that if no url is there the image is going to get the default one. So add that default case and see if it works.

If any of the above point is not clear feel free to comment.

varun bhardwaj
  • 1,522
  • 13
  • 24
  • But the if and else if are mutually exclusive. The condoms always satisfy given the options for message sending. Check out the Group Messaging class. When sending a normal message they are forced to use "0","0" for the location and image sharing. – Sauron Feb 24 '15 at 05:29
  • Change your answer to include the .equals("0") and it would be correct, – Sauron Feb 25 '15 at 00:03