I have chat app
In custom array adapter. I set random colors to usernames for each message with this code:
String[] array = context.getResources().getStringArray(R.array.username_colors);
randomColor = array[new Random().nextInt(array.length)];
nameTextView.setTextColor(Color.parseColor(randomColor));
When new message arrive I add it to listview, and call adapter.notifyDataSetChanged();
This causes recoloring existing usernames in messages each time.
How can I prevent recoloring existing items in listview when calling adapter.notifyDataSetChanged();
Edit 1
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ChatMessageElement el = list.get(position);
ViewHolder holder = null;
NewMessagesLabelHolder labelHolder = null;
if (convertView == null) {
convertView = el.getView(inflater, parent);
if (el.isMessage()) {
holder = new ViewHolder();
holder.messageLayout = (RelativeLayout) convertView.findViewById(R.id.message_container);
holder.messageContent = (LinearLayout) convertView.findViewById(R.id.message_content);
holder.bottomIndicator = (LinearLayout) convertView.findViewById(R.id.bottom_indicators);
holder.dateTextView = (TextView) convertView.findViewById(R.id.message_date);
holder.timeAgo = (TextView) convertView.findViewById(R.id.time_ago);
holder.nameTextView = (TextView) convertView.findViewById(R.id.user_name);
holder.likesCountTextView = (TextView) convertView.findViewById(R.id.likes_count);
holder.likesLabelImageView = (ImageView) convertView.findViewById(R.id.likes_label);
holder.spamCountTextView = (TextView) convertView.findViewById(R.id.spam_count);
holder.spamLabelImageView = (ImageView) convertView.findViewById(R.id.spam_label);
holder.avatarImageView = (ImageView) convertView.findViewById(R.id.avatar);
holder.statusImageView = (ImageView) convertView.findViewById(R.id.delivered_label);
holder.progressBar = (ProgressBar) convertView.findViewById(R.id.progress_bar);
holder.errorSign = (ImageView) convertView.findViewById(R.id.error_sign);
holder.spamSign = (ImageView) convertView.findViewById(R.id.spam_sign);
holder.bookmarkLabel = (ImageView) convertView.findViewById(R.id.bookmark_label);
holder.topIndicators = (LinearLayout) convertView.findViewById(R.id.topIndicators);
convertView.setTag(holder);
}
if (el.isNewMessagesLabel()) {
convertView = inflater.inflate(R.layout.chat_new_messages_label_layout, parent, false);
labelHolder = new NewMessagesLabelHolder();
labelHolder.newMessagesLabel = (TextView) convertView.findViewById(R.id.new_messages_label);
convertView.setTag(labelHolder);
}
} else {
if (el.isMessage()) {
holder = (ViewHolder) convertView.getTag();
}
if (el.isNewMessagesLabel()) {
labelHolder = (NewMessagesLabelHolder) convertView.getTag();
}
}
if (el.isMessage()) {
Message currentMessage = (Message) el;
drawMessage(holder, currentMessage, position);
}
if (el.isNewMessagesLabel()) {
NewMessagesLabel messagesLabel = (NewMessagesLabel) el;
drawNewMessagesLabel(labelHolder, messagesLabel);
}
return convertView;
}
private void drawMessage(ViewHolder holder, Message message, int position) {
String date = message.getCreatedAt();
String formattedDate = DateHelper.getInstance(context).formatDate("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "HH:mm", date);
String userName = message.getUserName();
holder.likesLabelImageView.setVisibility(View.GONE);
holder.likesCountTextView.setVisibility(View.GONE);
holder.spamCountTextView.setVisibility(View.GONE);
holder.spamLabelImageView.setVisibility(View.GONE);
holder.bookmarkLabel.setVisibility(View.GONE);
holder.statusImageView.setVisibility(View.GONE);
holder.progressBar.setVisibility(View.GONE);
holder.statusImageView.setVisibility(View.GONE);
holder.errorSign.setVisibility(View.GONE);
holder.spamSign.setVisibility(View.GONE);
holder.timeAgo.setVisibility(View.GONE);
holder.timeAgo.setText("");
holder.messageLayout.setAlpha(1f);
holder.topIndicators.setVisibility(View.VISIBLE);
if (message.isNewDay()) {
holder.timeAgo.setVisibility(View.VISIBLE);
String dayDate = DateHelper.getInstance(context).formatDate("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "MMMM d, yyyy", date);
//String dayDate = getTimeAgo(mHelper.millisFromString(message.getCreatedAt()), context);
holder.timeAgo.setText(dayDate);
}else{
holder.timeAgo.setVisibility(View.GONE);
}
holder.avatarImageView.setImageResource(R.drawable.com_facebook_profile_default_icon);
if (GrouviDatabaseManager.getInstance(context).getCurrentUser().getId() == message.getUserId()) {
userName = USERNAME_ME;
if (message.getStatus() != null && message.getStatus().equals(Message.MSG_STATUS_SEND)) {
holder.statusImageView.setBackgroundResource(R.drawable.icon_chat_message_delivered);
holder.statusImageView.setVisibility(View.VISIBLE);
}
if (message.getStatus() != null && message.getStatus().equals(Message.MSG_STATUS_SENDING)) {
holder.progressBar.setVisibility(View.VISIBLE);
}
if (message.getStatus() != null && message.getStatus().equals(Message.MSG_STATUS_LOCAL)) {
holder.statusImageView.setBackgroundResource(R.drawable.icon_chat_message_delivered);
holder.statusImageView.setVisibility(View.VISIBLE);
}
if (message.getStatus() == null || message.getStatus().equals(Message.MSG_STATUS_ERROR)) {
holder.messageLayout.setAlpha(0.4f);
holder.errorSign.setVisibility(View.VISIBLE);
}
}
if (message.getSpamCount() > 0 && currentMode == MODE_NORMAL) {
holder.messageLayout.setAlpha(0.4f);
holder.spamSign.setVisibility(View.VISIBLE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
holder.messageContent.setLayoutParams(params);
holder.spamCountTextView.setText(Integer.toString(message.getSpamCount()));
holder.spamCountTextView.setVisibility(View.VISIBLE);
holder.spamLabelImageView.setVisibility(View.VISIBLE);
} else {
holder.messageLayout.setAlpha(1f);
holder.spamSign.setVisibility(View.GONE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
holder.messageContent.setLayoutParams(params);
}
if (currentMode == MODE_REPORT) {
String timeAgo = getTimeAgo(mHelper.millisFromString(message.getCreatedAt()));
holder.timeAgo.setText(timeAgo);
holder.timeAgo.setVisibility(View.VISIBLE);
}
if (message.getUserAvatar() != null && !message.getUserAvatar().isEmpty()) {
try {
Picasso
.with(context)
.load(message.getUserAvatar())
.error(R.drawable.com_facebook_profile_default_icon)
.placeholder(R.drawable.com_facebook_profile_default_icon)
.into(holder.avatarImageView);
} catch (Exception e) {
Log.e("Main", e.getMessage(), e);
}
}
colorUsername(holder, message, userName);
holder.nameTextView.setText(userName);
holder.dateTextView.setText(formattedDate);
if (message.getLikesCount()>0) {
holder.likesCountTextView.setText(Integer.toString(message.getLikesCount()));
holder.likesCountTextView.setVisibility(View.VISIBLE);
holder.likesLabelImageView.setVisibility(View.VISIBLE);
}
if (message.isBookmarked()) {
holder.bookmarkLabel.setVisibility(View.VISIBLE);
}
List<MessageComponent> messageComponentList;
messageComponentList = message.getMessageComponents();
drawMessageContent(holder, messageComponentList, message);
holder.nameTextView.setTag(position);
holder.avatarImageView.setTag(position);
holder.nameTextView.setOnClickListener(userClickListener);
holder.avatarImageView.setOnClickListener(userClickListener);
// hang empty onLingClickListener to display context menu when
// long click on whole message
holder.nameTextView.setOnLongClickListener(longClickListener);
holder.avatarImageView.setOnLongClickListener(longClickListener);
}
private void colorUsername(ViewHolder holder, Message message, String userName) {
String randomColor = prevColor;
if (userName.equals(USERNAME_ME)){
randomColor = "#000000";
}else if (message.getUserId()!=prevMsgUserID) {
do {
String[] array = context.getResources().getStringArray(R.array.username_colors);
randomColor = array[new Random().nextInt(array.length)];
}while (prevColor.equals(randomColor));
}
holder.nameTextView.setTextColor(Color.parseColor(randomColor));
prevColor = randomColor;
prevMsgUserID = message.getUserId();
}
You should keep color in the data class, for example in the Message class, or keep Map in the adapter, that maps Message to Color. Then randomly create a color, when it doesn't present in the map. or use the color, if it present in the map. Using a map is good solution than keeping in the data class, when the color doesn't related to message, when it is not a message property, so in that case, a good solution is a keeping it in the adapter class, in the map, for example
private Map<Message, String> colorsMap = new HashMap<Message, String>();
private void colorUsername(ViewHolder holder, Message message, String userName) {
String randomColor;
if(colorsMap.contains(message)) {
randomColor = colorsMap.get(message);
}
else {
if (userName.equals(USERNAME_ME)){
randomColor = "#000000";
}else if (message.getUserId()!=prevMsgUserID) {
do {
String[] array = context.getResources().getStringArray(R.array.username_colors);
randomColor = array[new Random().nextInt(array.length)];
}while (prevColor.equals(randomColor));
}
colorsMap.put(message, randomColor);
}
holder.nameTextView.setTextColor(Color.parseColor(randomColor));
}
Basically you have to create a Collection of user data model.
Like ArrayList<UserModel> arr = new ArrayList<UserModel>();
User Model can contain-> userId,userColor,groupId(if group chat supported) and map this model with you DB.
Means you have to make a column in db and add userBgColor in user table and map it with the model and this model in array list and supply the array list to your custom adapter .
Your can use ORMLite for rational mapping .
Then in getView()
{
UserModel model = arr.get(position);
String color = user.getUserColor();
}
Related
Trying to fetch data from SQLite and initialize some text view data but the problem is that text view does not show the data that initialize inside the try-catch block. Is there any better solution to accomplish this problem?
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
AdmissionViewHolder viewHolder;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.followup_listview_row_layout, parent, false);
viewHolder = new AdmissionViewHolder();
viewHolder.p_type = (TextView) row.findViewById(R.id.p_type);
viewHolder.pName_Age = (TextView) row.findViewById(R.id.p_name_age);
viewHolder.admissionDateTime = (TextView) row.findViewById(R.id.admission_date_time);
viewHolder.facilityName = (TextView) row.findViewById(R.id.facility_name);
viewHolder.sex = (TextView) row.findViewById(R.id.sex);
viewHolder.followup_Item = (TextView) row.findViewById(R.id.followup);
viewHolder.followupItem = (Button) row.findViewById(R.id.followup_item);
viewHolder.itemInfo = (ImageView) row.findViewById(R.id.item_info);
viewHolder.arrow = (ImageButton) row.findViewById(R.id.arrow_button);
viewHolder.hiddenView = (TableLayout) row.findViewById(R.id.hiddenView);
viewHolder.ps_m = (TextView) row.findViewById(R.id.txt_s_pm);
viewHolder.ps_e = (TextView) row.findViewById(R.id.txt_s_pe);
viewHolder.ps_n = (TextView) row.findViewById(R.id.txt_s_pn);
viewHolder.ts_m = (TextView) row.findViewById(R.id.txt_s_tm);
viewHolder.ts_e = (TextView) row.findViewById(R.id.txt_s_te);
viewHolder.ts_n = (TextView) row.findViewById(R.id.txt_s_tn);
row.setTag(viewHolder);
} else {
viewHolder = (AdmissionViewHolder)row.getTag();
}
AdmissionModel admissionModel = getItem(position);
String pAge = String.format("%dy %dm %dd",admissionModel.AgeYears,admissionModel.AgeMonths,admissionModel.AgeDays);
viewHolder.p_type.setText(admissionModel.PtType);
viewHolder.pName_Age.setText(String.format("%s (%s)",admissionModel.PtName,pAge));
viewHolder.admissionDateTime.setText(String.format("%s %s",admissionModel.HosAdmDate,admissionModel.HosAdmTime));
viewHolder.facilityName.setText(admissionModel.FacilityName);
viewHolder.sex.setText(admissionModel.SexName);
viewHolder.itemInfo.setOnClickListener(this);
viewHolder.itemInfo.setTag(position);
viewHolder.followupItem.setOnClickListener(this);
viewHolder.followupItem.setTag(position);
viewHolder.followup_Item.setOnClickListener(this);
viewHolder.followup_Item.setTag(position);
viewHolder.arrow.setOnClickListener(v -> clickedListener.buttonClicked(admissionModel));
viewHolder.arrow.setTag(position);
try {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date();
String toDay = formatter.format(date);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
String previousDay = formatter.format(cal.getTime());
List<FollowupModel> followupModelList = dbHelper.GetFollowupData(admissionModel.NtfSL,previousDay,toDay);
if(followupModelList.size()>0){
Map<String, List<FollowupModel>> groupByDateList = Stream.of(followupModelList).collect(
Collectors.groupingBy(e->e.FollowupDateyyyMMdd));
for (String dataKey : groupByDateList.keySet()){
if(dataKey.equals(previousDay)){
for (FollowupModel followupModel : groupByDateList.get(dataKey)){
if(followupModel.Type == 1){
viewHolder.ps_m = setPatientStatus(followupModel.PtStatus);
}else if(followupModel.Type == 2){
viewHolder.ps_e = setPatientStatus(followupModel.PtStatus);
}else if(followupModel.Type == 3){
viewHolder.ps_n = setPatientStatus(followupModel.PtStatus);
}
}
}else if(dataKey.equals(toDay)){
for (FollowupModel followupModel : groupByDateList.get(dataKey)){
if(followupModel.Type == 1){
viewHolder.ts_m = setPatientStatus(followupModel.PtStatus);
}else if(followupModel.Type == 2){
viewHolder.ts_e = setPatientStatus(followupModel.PtStatus);
}else if(followupModel.Type == 3){
viewHolder.ts_n = setPatientStatus(followupModel.PtStatus);
}
}
}
}
}
} catch (ParseException e) {
e.printStackTrace();
}
if(admissionModel.isTableLayoutVisible){
viewHolder.hiddenView.setVisibility(View.VISIBLE);
viewHolder.arrow.setImageResource(R.drawable.ic_baseline_expand_less_24);
}else{
viewHolder.hiddenView.setVisibility(View.GONE);
viewHolder.arrow.setImageResource(R.drawable.ic_baseline_expand_more_24);
}
return row;
}
Here getView() will be called every time when your layout is inflated .
Below line is heavy operation .
List<FollowupModel> followupModelList = dbHelper.GetFollowupData(admissionModel.NtfSL,previousDay,toDay);
You will have to move this to other class and pass required info as a parameter/list to your custom adapter class
I'm using ExpandapbeListView its work perfect all expand and collapse but I just want to update only particular child item here when I click on plus value should be update in EditText and I don't want to use notifyDatasetChanged() Just want to update only particular field and also i should able to update EditText directly. It can have multiple child item.
Ex: Colgate may have multiple child Item like 100gm,200gm,300gm
So when I click on Plus It should able to get Id of EditText and Update Quantity
#Override
public View getChildView(int productPos, int weightPos, boolean b, View plusMinusView, ViewGroup viewGroup) {
if (plusMinusView == null) {
csHolder = new ChildHolder();
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
plusMinusView = inflater.inflate(R.layout.orders_products_plus_minus_design, null);
}
csHolder.minQty = (TextView) plusMinusView.findViewById(R.id.orderProducts_submitMinQtyTxt);
csHolder.totalPriceTxt = (TextView) plusMinusView.findViewById(R.id.orderProducts_submitTotalPriceTxt);
csHolder.weightTxt = (TextView) plusMinusView.findViewById(R.id.orderProducts_submitWeightTxt);
csHolder.unitPrice = (TextView) plusMinusView.findViewById(R.id.orderProducts_submitUnitPriceTxt);
csHolder.totalTaxTxt = (TextView) plusMinusView.findViewById(R.id.orderProducts_submitTotalTaxTxt);
csHolder.netPriceTxt = (TextView) plusMinusView.findViewById(R.id.orderProducts_submitNetPriceTxt);
csHolder.orderQtyEdit = (CustomEditText) plusMinusView.findViewById(R.id.orderProducts_orderQtyTxt);
csHolder.plusTxt = (RelativeLayout) plusMinusView.findViewById(R.id.orderProducts_plusTxtLay);
csHolder.minusTxt = (RelativeLayout) plusMinusView.findViewById(R.id.orderProducts_minusTxtLay);
plusMinusView.setTag(productPos + "_" + weightPos);
String tag = "weight_" + productPos + "_" + weightPos;
csHolder.orderQtyEdit.setTag(tag);
csHolder.plusTxt.setTag(tag);
csHolder.minusTxt.setTag(tag);
//csHolder.plusTxt.setOnClickListener(weightClick);
//csHolder.minusTxt.setOnClickListener(weightClick);
final View finalPlusMinusView = plusMinusView;
csHolder.plusTxt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
csHolder.orderQtyEdit.setText("5");
}
});
if(!csStatus.equalsIgnoreCase("DRAFT")) {
csHolder.plusTxt.setVisibility(View.GONE);
csHolder.minusTxt.setVisibility(View.GONE);
csHolder.orderQtyEdit.setEnabled(false);
}
else
{
csHolder.plusTxt.setVisibility(View.VISIBLE);
csHolder.minusTxt.setVisibility(View.VISIBLE);
csHolder.orderQtyEdit.setEnabled(true);
}
try
{
csHolder.orderQtyEdit.addTextChangedListener(new MyTextWatcher(csHolder.orderQtyEdit));
JSONObject weighObj = csMainArr.getJSONObject(productPos).getJSONArray("weights").getJSONObject(weightPos);
if(weighObj.has("unit"))
{
csHolder.weightTxt.setText(weighObj.getString("unit"));
}
if (weighObj.has("order_qty") == false)
weighObj.put("order_qty", "0");
if (weighObj.has("sell_price") == false)
weighObj.put("sell_price", "0");
if (weighObj.has("order_qty") == false)
{
csHolder.totalPriceTxt.setText("0.00");
csHolder.totalTaxTxt.setText("0.00");
csHolder.netPriceTxt.setText("0.00");
}
else {
int qty = 0;
double sellPrice = 0.00;
float tax = 0f;
double totalPrice = 0.00;
double totalTax = 0.00;
double netPrice = 0.00;
if(csStatus.equals("DRAFT")) {
qty = Integer.parseInt(weighObj.getString("order_qty"));
sellPrice = weighObj.getDouble("sell_price");
}
else
{
qty = Integer.parseInt(weighObj.has("qty") ? weighObj.getString("qty"):"0");
sellPrice = weighObj.getDouble("unit_price");
}
tax = Float.parseFloat(csMainArr.getJSONObject(productPos).has("tax") ? csMainArr.getJSONObject(productPos).getString("tax") : "0");
totalPrice = qty*sellPrice;
totalTax = (totalPrice*tax)/100;
netPrice = totalPrice + totalTax;
csHolder.totalPriceTxt.setText(getResources().getString(R.string.Rs)+" "+String.format("%.2f",totalPrice));
csHolder.totalTaxTxt.setText(getResources().getString(R.string.Rs)+" "+String.format("%.2f",totalTax));
csHolder.netPriceTxt.setText(getResources().getString(R.string.Rs)+" "+String.format("%.2f",netPrice));
}
csHolder.orderQtyEdit.isValueChangeMySelf = true;
if(csStatus.equals("DRAFT"))
csHolder.orderQtyEdit.setText(weighObj.getString("order_qty"));
else
csHolder.orderQtyEdit.setText(weighObj.has("qty")?weighObj.getString("qty"):"0");
/*if(weightPos == iClickedItem) {
csHolder.orderQtyEdit.requestFocus();
}
else {
csHolder.orderQtyEdit.clearFocus();
}*/
if(csStatus.equals("DRAFT"))
csHolder.unitPrice.setText(getResources().getString(R.string.Rs)+" "+String.format("%.2f",weighObj.has("sell_price")?weighObj.getDouble("sell_price") : 0.00));
else
csHolder.unitPrice.setText(getResources().getString(R.string.Rs)+" "+String.format("%.2f",weighObj.has("unit_price")?weighObj.getDouble("unit_price") : 0.00));
csHolder.minQty.setText(weighObj.has("min_order_qty")?weighObj.getString("min_order_qty"):"0");
//View line = (View) plusMinusView.findViewById(R.id.orderProducts_submitDividerLine);
//if(isLast)
// line.setVisibility(View.GONE);
}
catch(Exception e)
{
}
return plusMinusView;
}
I'm an Android beginner and I can't figure out why this is happening.
Activity Screenshot:
Everything works fine except when I scroll down (hence why I think it has to do with recycling)... So when I scroll back up and attempt to undo the vote (red arrow) on the first post, it thinks the post is voted down!
Alternatively, it may also think the down-vote ImageButton drawable is empty - see code). If I don't scroll, it works perfectly.
getView code:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
// inflate the list item
convertView = this.inflater.inflate(R.layout.row_layout, parent, false);
// get views
holder.profilePic = (ImageView) convertView.findViewById(R.id.profilePic);
holder.username = (TextView) convertView.findViewById(R.id.username);
holder.day = (TextView) convertView.findViewById(R.id.day);
holder.rating = (TextView) convertView.findViewById(R.id.rating);
holder.textPost = (TextView) convertView.findViewById(R.id.textPost);
holder.ratingUp = (ImageButton) convertView.findViewById(R.id.ratingUp);
holder.ratingDown = (ImageButton) convertView.findViewById(R.id.ratingDown);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final Drawable up_clicked = context.getResources().getDrawable(R.drawable.ic_action_rate_up_clicked);
final Drawable up_unClicked = context.getResources().getDrawable(R.drawable.ic_action_rate_up);
final Drawable down_clicked = context.getResources().getDrawable(R.drawable.ic_action_rate_down_clicked);
final Drawable down_unClicked = context.getResources().getDrawable(R.drawable.ic_action_rate_down);
Post post = cityFeed.get(position);
holder.profilePic.setImageResource(post.getDrawableID());
holder.username.setText(post.getUsername());
holder.day.setText(post.getDay());
holder.rating.setText(post.getRating());
holder.textPost.setText(post.getText());
db = new DatabaseHandler(context);
String userVotesUp = null;
userVotesUp = db.getUserVotes("up");
if (userVotesUp == null) {
userVotesUp = "";
}
String userVotesDown = null;
userVotesDown = db.getUserVotes("down");
if (userVotesDown == null) {
userVotesDown = "";
}
String postID = post.getPostID();
if (userVotesUp.contains(postID)) {
holder.ratingUp.setImageDrawable(up_clicked);
} else if (userVotesDown.contains(postID) && userVotesUp != null) {
holder.ratingDown.setImageDrawable(down_clicked);
} else {
holder.ratingUp.setImageDrawable(up_unClicked);
holder.ratingDown.setImageDrawable(down_unClicked);
}
db.close();
holder.ratingUp.setTag(position);
holder.ratingDown.setTag(position);
holder.ratingUp.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View convertView) {
// get post details using button tag
int pos = (Integer)convertView.getTag();
Post post = cityFeed.get(pos);
String postID = post.getPostID();
String ratingString = post.getRating();
int ratingValue = Integer.parseInt(ratingString);
RelativeLayout parent = (RelativeLayout)convertView.getParent().getParent();
TextView ratingView = (TextView)parent.findViewById(R.id.rating);
ImageButton up = (ImageButton)parent.findViewById(R.id.ratingUp);
ImageButton down = (ImageButton)parent.findViewById(R.id.ratingDown);
// if the post is not voted down...
if (down.getDrawable() == down_unClicked) {
// if the post is not voted up...
if (up.getDrawable() == up_unClicked) {
up.setImageDrawable(up_clicked);
ratingValue = ratingValue + 1;
ratingString = Integer.toString(ratingValue);
ratingView.setText(ratingString);
post.setRating(ratingString);
wsAsync = new WebServiceAsync(context);
wsAsync.execute(voteTag, postID, "up");
// else the post is voted up...
} else {
up.setImageDrawable(up_unClicked);
ratingValue = ratingValue - 1;
ratingString = Integer.toString(ratingValue);
ratingView.setText(ratingString);
post.setRating(ratingString);
wsAsync = new WebServiceAsync(context);
wsAsync.execute(voteTag, postID, "down");
}
// else the post is voted down...
} else {
down.setImageDrawable(down_unClicked);
up.setImageDrawable(up_clicked);
ratingValue = ratingValue + 2;
ratingString = Integer.toString(ratingValue);
ratingView.setText(ratingString);
post.setRating(ratingString);
wsAsync = new WebServiceAsync(context);
wsAsync.execute(voteTag, postID, "upDownAlready");
}
}
});
holder.ratingDown.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View convertView) {
// get post details using button tag
int pos = (Integer)convertView.getTag();
Post post = cityFeed.get(pos);
String postID = post.getPostID();
String ratingString = post.getRating();
int ratingValue = Integer.parseInt(ratingString);
RelativeLayout parent = (RelativeLayout)convertView.getParent().getParent();
TextView ratingView = (TextView)parent.findViewById(R.id.rating);
ImageButton up = (ImageButton)parent.findViewById(R.id.ratingUp);
ImageButton down = (ImageButton)parent.findViewById(R.id.ratingDown);
// if the post is not voted up...
if (up.getDrawable() == up_unClicked) {
// if the post is not voted down...
if (down.getDrawable() == down_unClicked) {
down.setImageDrawable(down_clicked);
ratingValue = ratingValue - 1;
ratingString = Integer.toString(ratingValue);
ratingView.setText(ratingString);
post.setRating(ratingString);
wsAsync = new WebServiceAsync(context);
wsAsync.execute(voteTag, postID, "down");
// else the post is voted down...
} else {
down.setImageDrawable(down_unClicked);
ratingValue = ratingValue + 1;
ratingString = Integer.toString(ratingValue);
ratingView.setText(ratingString);
post.setRating(ratingString);
wsAsync = new WebServiceAsync(context);
wsAsync.execute(voteTag, postID, "up");
}
// else the post is voted up...
} else {
up.setImageDrawable(up_unClicked);
down.setImageDrawable(down_clicked);
ratingValue = ratingValue - 2;
ratingString = Integer.toString(ratingValue);
ratingView.setText(ratingString);
post.setRating(ratingString);
wsAsync = new WebServiceAsync(context);
wsAsync.execute(voteTag, postID, "downUpAlready");
}
}
});
return convertView;
}
By considering that your onClickListerners(on holder.ratingUp and holder.ratingDown) works fine, i think the problem is in this portion of your code
if (userVotesUp.contains(postID)) {
holder.ratingUp.setImageDrawable(up_clicked);
} else if (userVotesDown.contains(postID) && userVotesUp != null) {
holder.ratingDown.setImageDrawable(down_clicked);
} else {
holder.ratingUp.setImageDrawable(up_unClicked);
holder.ratingDown.setImageDrawable(down_unClicked);
}
If i am not wrong, you are doing something like that you have 3 conditions, First is
if (userVotesUp.contains(postID))
that means rating is upvoted and you are setting up_clicked imageDrawable, but you are not setting down_unClicked image drawable to holder.ratingDown.
second condition applies to this
if (userVotesUp.contains(postID))
then you are setting down_clicked drawable to holder.ratingDown, but not setting up_unClicked image drawable to holder.ratingUp.
and third condition is neither upvoted nor downvoted and that seems to be fine. so I think, you have to replace your that portion of code with this
if (userVotesUp.contains(postID)) {
holder.ratingUp.setImageDrawable(up_clicked);
holder.ratingDown.setImageDrawable(down_unClicked);
} else if (userVotesDown.contains(postID) && userVotesUp != null) {
holder.ratingDown.setImageDrawable(down_clicked);
holder.ratingUp.setImageDrawable(up_unClicked);
} else {
holder.ratingUp.setImageDrawable(up_unClicked);
holder.ratingDown.setImageDrawable(down_unClicked);
}
Hope this helps..!!
I want to the change the text of the button which was clicked in a getView function. The text is changed but when the view is scrolled the text of other buttons which the same id is also changed. I don't want that. I want only the text of the button which was clicked to be changed.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final int i=position;
List dialog = DialogList.get(i);
final Object memid = dialog.get(2).toString();
final String dialogid = dialog.get(3).toString();
final String dialogtype = dialog.get(4).toString();
ImageView imageViews;
if (convertView == null) {
LayoutInflater layoutInflator = LayoutInflater.from(getContext());
convertView = layoutInflator.inflate(R.layout.invite_friends_list, null);
holder = new ViewHolder();
holder.friendsname = (TextView) convertView.findViewById(R.id.friendsname);
holder.profimage = (ImageView) convertView.findViewById(R.id.member_image);
holder.assign = (Button) convertView.findViewById(R.id.btnInvite);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
holder.friendsname.setText(user_name);
holder.assign.setTag(holder);
holder.assign.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("assigntext", holder.assign.getText().toString());
SharedPreferences prfs = _context.getSharedPreferences("MyPref",
Context.MODE_PRIVATE);
String token = prfs.getString("apptoken", "");
String url = null;
if(dialogtype.equals("V"))
{
url = "http://www.jjhjjkh.com/index.php?/alkjlkjlk/dialog/invjlkjlkjklialogmember?apptoken="
+ token + "&dialogid=" + dialogid+"&mid="+memid.toString();
}
if(dialogtype.equals("P"))
{
url = "http://www.ckjhuihiuhiu.com/index.php?/kjij/dialog/inviuhuihuihuimember?apptoken="
+ token + "&dialogid=" + dialogid+"&mid="+memid.toString();
}
List<String> urlList = new ArrayList<String>();
Log.d("cat",url.toString());
// JSON Node names
String TAG_DETAILS = "invitemembers";
String TAG_MSG = "msg";
// contacts JSONArray
JSONArray dialogpublish = null;
JSONArray dialogs = null;
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
// Log.d("cat",json.toString());
try {
dialogpublish = json.getJSONArray(TAG_DETAILS);
// Log.d("apptoken",login.toString());
for (int i = 0; i < dialogpublish.length(); i++) {
JSONObject d = dialogpublish.getJSONObject(i);
String msg = d.getString(TAG_MSG);
//dialogs = d.getJSONArray("updatedialog");
if (msg.equals("success")) {
// ViewHolder mH = (ViewHolder)view.getTag();
//Integer currentPos = view.getTag();
String mem_id= view.getTag().toString();
if(mem_id.equals(memid))
{
Toast.makeText(_context, "Member invited Succesfully",Toast.LENGTH_LONG).show();
ViewHolder mH = (ViewHolder)view.getTag();
mH.assign.setText("Invited");
}
//view.setText("Invited");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
I guess that is happenning because you are using the viewholder pattern. The viewholder pattern tends to cache views for performance optimization. try to write the adapter without using viewholder. If the list view items arent large in numbers.
Create a new HashMap in Adapter :
private HashMap<Integer, String> buttonTitleMap=new HashMap<Integer, String>();
Create a function getButtonTitle as below in Adapter :
private String getButtonTitle(int position){
if(buttonTitleMap.containsKey(position)){
return buttonTitleMap.get(position);
}else{
return "Your Normal Button text";
}
}
Then in getView() of Adapter, befor returning convertView, call :
....
holder.assign.setText(getButtonTitle(position));
holder.friendsname.setTag(position);
return convertView;
}
When the Button is clicked, you can get the list item position of the button. So what you need to do is to change the button title as you do before and also update the hashmap with the same value :
holder.assign.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
....
mH.assign.setText("Invited");
int position = (int)mH.friendsname.getTag();
buttonTitleMap.put(position,"Invited");
....
}
}
You are done.
Try
String mem_id= view.getTag().toString();
if(mem_id.equals(memid))
{
Toast.makeText(_context, "Member invited Succesfully",Toast.LENGTH_LONG).show();
((Button)view).setText("Invited");
}
I have a list with ImageView and TextView. I read a scann time and for the specified position of textview has to be set. This is done i a right way, but after srolling down and then up another textview in Listview is set. I am seeing that this is not new, but I could not solve this problem.Any idea?? BaseAdapter is in the following. I tried for more then a week but no solution
#Override
public View getView( final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
Log.d("convertView", "NULLL");
convertView = LayoutInflater.from(mContenxt).inflate(
R.layout.list_items, null);
holder = new ViewHolder();
holder.textView = (TextView) convertView
.findViewById(R.id.placeName);
holder.imageView = (ImageView) convertView
.findViewById(R.id.itemSymbole);
holder.textDate = (TextView) convertView
.findViewById(R.id.txtViewTimeAndDate);
holder.imageMap = (ImageView)convertView.findViewById(R.id.imageViewMap);
holder.linearLayoutText = ( LinearLayout)convertView.findViewById(R.id.txtViewList);
holder.linearLayoutImage = ( LinearLayout)convertView.findViewById(R.id.thumbnail);
convertView.setTag(holder);
}
Log.d("convertView", "Not NULLLL");
holder = (ViewHolder) convertView.getTag();
holder.id = position;
holder.textView.setText(items.get(position).get("ProductName"));
holder.imageView.setId(position);
holder.linearLayoutText.setBackgroundColor(position);
if (items.get(position).get("Identifier")
.equals(com.metasec.wachmann.ItemActivity.uID)) {
holder.linearLayoutText.setBackgroundColor(Color.CYAN);
holder.imageView.setImageResource(R.drawable.ok);
Log.d("TIMEEEE", ItemActivity.scannDateAndTime);
holder.textDate.setText(ItemActivity.scannDateAndTime);
notifyDataSetChanged();
}else {
holder.imageView.setImageResource(R.drawable.not_ok);
holder.textDate.setText("");
notifyDataSetChanged();
}
holder.linearLayoutText.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
holder.linearLayoutText.setBackgroundColor(position);
holder.linearLayoutText.setBackgroundColor(Color.RED);
notifyDataSetChanged();
String placeName = items.get(position).get("ProductName");
String identifier = items.get(position).get("Identifier");
String itemId = items.get(position).get("ItemId");
String propertyBaseId = null;
String gpsCoordinates = null;
GPSTracker gpsTracker = new GPSTracker(mContenxt);
gpsTracker.stopUsingGPS();
double latitude = 0;
double longitude = 0;
if (gpsTracker.canGetLocation()) {
latitude = gpsTracker.getLatitude();
longitude = gpsTracker.getLongitude();
gpsCoordinates = latitude + ", " + longitude;
}
for (int k = 0; k < LoggedActivity.propertyBaseList.size(); k++) {
if (LoggedActivity.propertyBaseList.get(k).getName()
.equals("xxxxxxx")) {
propertyBaseId = LoggedActivity.propertyBaseList.get(k)
.getPropertyBaseId();
Intent intentSenderDataToServer = new Intent(mContenxt,
SenderReportDemageToServerActivity.class);
// give ItemId
intentSenderDataToServer.putExtra(ITEM_ID, itemId);
// give GroupId
intentSenderDataToServer.putExtra(PRODUCT_NAME,
placeName);
// give GroupName
intentSenderDataToServer.putExtra(IDENTIFIER,
identifier);
// give PropertyBaseID
intentSenderDataToServer.putExtra(PROPERTY_BASE_ID,
propertyBaseId);
// give GPS Coordinates
intentSenderDataToServer.putExtra(GPS_COORDINATES,
gpsCoordinates);
Log.d("items.get(position).get(ProductNNNNName)", items
.get(position).get("ProductName"));
intentSenderDataToServer.putExtra("ProductName",
placeName);
intentSenderDataToServer.putExtra("Identifier",
identifier);
mContenxt.startActivity(intentSenderDataToServer);
} // END IF Loop
} // END FOR Loop
}
});
holder.imageMap.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String placeName = items.get(position).get("ProductName");
String identifier = items.get(position).get("Identifier");
String itemId = items.get(position).get("ItemId");
Log.d("placeName11",placeName);
Log.d("identifier111",identifier);
Log.d("itemId111",itemId);
Intent intentWachmanMapActivitiy = new Intent(mContenxt,
WachmanOpenStreetMapViewActivity.class);
intentWachmanMapActivitiy.putExtra(ITEM_ID, itemId);
// give GroupId
intentWachmanMapActivitiy.putExtra(PRODUCT_NAME,
placeName);
// give GroupName
intentWachmanMapActivitiy.putExtra(IDENTIFIER,
identifier);
Log.d("items.get(position).get(ProductNNNNName)", items
.get(position).get("ProductName"));
intentWachmanMapActivitiy.putExtra("ProductName",
placeName);
intentWachmanMapActivitiy.putExtra("Identifier",
identifier);
mContenxt.startActivity(intentWachmanMapActivitiy);
}
});
return convertView;
}
static class ViewHolder {
TextView textView = null;
TextView textDate = null;
CheckBox checkbox = null;
ImageView imageView = null;
ImageView imageMap = null;
ImageButton imageButtonMap = null;
LinearLayout linearLayoutText = null;
LinearLayout linearLayoutImage = null;
int id;
}
And the following class shows where my own adapter would be called. I backgroudn I have to call my adapter ofter and the previous time and figure has to be remained.
private class SendBackground extends AsyncTask<Void, Void, Boolean>
{
#Override
protected void onPreExecute() {
mProgDialog = new ProgressDialog(getBaseContext());
mProgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgDialog = ProgressDialog.show(ItemActivity.this, "Sending", " Please Wait" );
}
#Override
protected Boolean doInBackground(Void... params) {
// TODO Auto-generated method stub
return httpRequest.postData(itemIdTmp, propertyBaseIdtmp, uID, coordinatesTmp);
}
#Override
protected void onPostExecute(Boolean result) {
Log.d("SendBackground", "onPostExecute");
if (result == true) {
Log.d("onPostExecute", "TRUE");
//mProgressBar.setVisibility(View.GONE);
mProgDialog.dismiss();
Toast.makeText(getApplicationContext(), "Data sent..",
Toast.LENGTH_LONG).show();
/*----------------------------->>>> Whenever from Server True is return then my oown adapter hast to be adapted, as mentioned the state and time of previous items have to be remained */
//setListAdapter(myBaseAdapterItemActivity);
listView.setAdapter(myBaseAdapterItemActivity);
myBaseAdapterItemActivity.notifyDataSetChanged();
} else {
mProgDialog.dismiss();
Toast.makeText(getApplicationContext(),
"Sending Data to Server failed", Toast.LENGTH_LONG)
.show();
}
}
}
// read all comments i write where need modifiaction
// Do not call notifiy dataset change inside adapter.
// if it will not work then i will write a sample code
#Override
public View getView( final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null; // use it
if (convertView == null) {
Log.d("convertView", "NULLL");
convertView = LayoutInflater.from(mContenxt).inflate(
R.layout.list_items, null);
holder = new ViewHolder();
holder.textView = (TextView) convertView
.findViewById(R.id.placeName);
holder.imageView = (ImageView) convertView
.findViewById(R.id.itemSymbole);
holder.textDate = (TextView) convertView
.findViewById(R.id.txtViewTimeAndDate);
holder.imageMap = (ImageView)convertView.findViewById(R.id.imageViewMap);
holder.linearLayoutText = ( LinearLayout)convertView.findViewById(R.id.txtViewList);
holder.linearLayoutImage = ( LinearLayout)convertView.findViewById(R.id.thumbnail);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag(); // new changes
Log.d("convertView", "Not NULLLL");
}
holder.id = position;
holder.textView.setText(items.get(position).get("ProductName"));
holder.imageView.setId(position); // why you set position it will cause error
//holder.linearLayoutText.setBackgroundColor(position);
if (items.get(position).get("Identifier")
.equals(com.metasec.wachmann.ItemActivity.uID)) {
holder.linearLayoutText.setBackgroundColor(Color.CYAN);
holder.imageView.setImageResource(R.drawable.ok);
Log.d("TIMEEEE", ItemActivity.scannDateAndTime);
holder.textDate.setText(ItemActivity.scannDateAndTime);
// notifyDataSetChanged(); no need to call it.
}else {
holder.imageView.setImageResource(R.drawable.not_ok);
holder.linearLayoutText.setBackgroundColor(Color.GREEN);
holder.textDate.setText("");
//notifyDataSetChanged(); no need to call it.
}
holder.linearLayoutText.setTag(position);
holder.linearLayoutText.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// holder.linearLayoutText.setBackgroundColor(position);
holder.linearLayoutText.setBackgroundColor(Color.RED);
// notifyDataSetChanged();
int selectedPosition = (Integer)v.getTag();
String placeName = items.get(selectedPosition).get("ProductName");
String identifier = items.get(selectedPosition).get("Identifier");
String itemId = items.get(selectedPosition).get("ItemId");
String propertyBaseId = null;
String gpsCoordinates = null;
GPSTracker gpsTracker = new GPSTracker(mContenxt);
gpsTracker.stopUsingGPS();
double latitude = 0;
double longitude = 0;
if (gpsTracker.canGetLocation()) {
latitude = gpsTracker.getLatitude();
longitude = gpsTracker.getLongitude();
gpsCoordinates = latitude + ", " + longitude;
}
// you are starting activity in lop it is dangerous because
// you are launching many activity.
// you should pass array
// i do not know are requirement.
for (int k = 0; k < LoggedActivity.propertyBaseList.size(); k++) {
if (LoggedActivity.propertyBaseList.get(k).getName()
.equals("xxxxxxx")) {
propertyBaseId = LoggedActivity.propertyBaseList.get(k)
.getPropertyBaseId();
Intent intentSenderDataToServer = new Intent(mContenxt,
SenderReportDemageToServerActivity.class);
// give ItemId
intentSenderDataToServer.putExtra(ITEM_ID, itemId);
// give GroupId
intentSenderDataToServer.putExtra(PRODUCT_NAME,
placeName);
// give GroupName
intentSenderDataToServer.putExtra(IDENTIFIER,
identifier);
// give PropertyBaseID
intentSenderDataToServer.putExtra(PROPERTY_BASE_ID,
propertyBaseId);
// give GPS Coordinates
intentSenderDataToServer.putExtra(GPS_COORDINATES,
gpsCoordinates);
Log.d("items.get(position).get(ProductNNNNName)", items
.get(position).get("ProductName"));
intentSenderDataToServer.putExtra("ProductName",
placeName);
intentSenderDataToServer.putExtra("Identifier",
identifier);
mContenxt.startActivity(intentSenderDataToServer);
} // END IF Loop
} // END FOR Loop
}
});
holder.imageMap.setTag(postion);
holder.imageMap.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int selectedPosition = (Integer)v.getTag();
String placeName = items.get(selectedPosition).get("ProductName");
String identifier = items.get(selectedPosition).get("Identifier");
String itemId = items.get(selectedPosition).get("ItemId");
Log.d("placeName11",placeName);
Log.d("identifier111",identifier);
Log.d("itemId111",itemId);
Intent intentWachmanMapActivitiy = new Intent(mContenxt,
WachmanOpenStreetMapViewActivity.class);
intentWachmanMapActivitiy.putExtra(ITEM_ID, itemId);
// give GroupId
intentWachmanMapActivitiy.putExtra(PRODUCT_NAME,
placeName);
// give GroupName
intentWachmanMapActivitiy.putExtra(IDENTIFIER,
identifier);
Log.d("items.get(position).get(ProductNNNNName)", items
.get(position).get("ProductName"));
intentWachmanMapActivitiy.putExtra("ProductName",
placeName);
intentWachmanMapActivitiy.putExtra("Identifier",
identifier);
mContenxt.startActivity(intentWachmanMapActivitiy);
}
});
return convertView;
}
static class ViewHolder {
TextView textView = null;
TextView textDate = null;
CheckBox checkbox = null;
ImageView imageView = null;
ImageView imageMap = null;
ImageButton imageButtonMap = null;
LinearLayout linearLayoutText = null;
LinearLayout linearLayoutImage = null;
int id;
}