Textview displaying "Hello World" instead of text set - android

I am having a listview. Initially I get such row item.
But when I scroll down, then at some positions I get this,
I am not getting why this is happening. Here I am using TreeObserver to get width of firsttext view, so as to get the length of string displayed in firsttextview and display the rest in other.
Here is the code for this, I have two layouts inflated, I am posting code for this one.
if(type==0){
if(convertView==null){
convertView= inflater.inflate(R.layout.incoming_msg_row,parent, false);
holder=new ViewHolder();
holder.messageFirstPart = (TextView) convertView
.findViewById(R.id.messageFirstPart);
holder.messageLeftPart = (TextView) convertView
.findViewById(R.id.messageLeftPart);
holder.username= (TextView) convertView.findViewById(R.id.SendersName);
holder.time=(TextView) convertView.findViewById(R.id.timestamp);
holder.leftline=convertView.findViewById(R.id.leftline);
holder.rightline=convertView.findViewById(R.id.rightline);
holder.view3=convertView.findViewById(R.id.incoming_msg_row_innerlayout);
convertView.setTag(holder);
}
else
holder = (ViewHolder) convertView.getTag();
holder.messageFirstPart.setText(message[position]);
holder.username.setText("John");
holder.time.setText(timestamp[position]);
RelativeLayout mineLayout=
(RelativeLayout)convertView.findViewById(R.id.incoming_msg_row_innerlayout);
RelativeLayout.LayoutParams params=(LayoutParams) mineLayout.getLayoutParams();
for(int i=0;i<x.length;i++){
System.out.println(x[i]);
if(position==x[i]){
holder.time.setVisibility(View.GONE);
holder.leftline.setVisibility(View.GONE);
holder.rightline.setVisibility(View.GONE);
params.topMargin=20;
// holder.view3.requestLayout();
mineLayout.setLayoutParams(params);
break;
}
else{
holder.time.setVisibility(View.VISIBLE);
holder.leftline.setVisibility(View.VISIBLE);
holder.rightline.setVisibility(View.VISIBLE);
// params.topMargin+=0;
// holder.view3.requestLayout();
params.topMargin=90;
mineLayout.setLayoutParams(params);
}
}
if(position==0){
holder.time.setVisibility(View.VISIBLE);
holder.leftline.setVisibility(View.VISIBLE);
holder.rightline.setVisibility(View.VISIBLE);
params.topMargin=90;
mineLayout.setLayoutParams(params);
}
holder.messageFirstPart.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
width = holder.messageFirstPart.getWidth();
int totalCharstoFit;
String chat = holder.messageFirstPart.getText().toString();
String substring=null,substringtwo=null;
totalCharstoFit =
holder.messageFirstPart.getPaint().breakText(chat, 0,
chat.length(), true, width, null);
substring = chat.substring(0, totalCharstoFit);
substringtwo = chat.substring(substring.length(),
chat.length());
holder.messageFirstPart.setText(chat);
holder.messageLeftPart.setText(substringtwo);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
holder.messageFirstPart.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
} else {
holder.messageFirstPart.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
}
}
});
}

Hello world is a constant text defined somewhere in strings or in xml for the textview.
Check in xml that whether you have given. android:text="Hello world" or you mentioned in strings.xml and used that in textview. android:text="#string/hello" if you mentioned that in strings.

Hello world is usually a sort of "default text" you get after you created a new project and, probably, when you create your ListView's row, in the xml, you left the android:text field set with that string, and because of the recycling system of the ListView you are getting the default text. you have probably forget to set the text for that TextView

Try to define adapter like this;
ListView lv = (ListView) dialog.findViewById(R.id.lv);
lv.refreshDrawableState();
AdapterClass adapter = new AdapterClass (context, R.layout.row, adpArray);
try {
adapter.setNotifyOnChange(true);
adapter.notifyDataSetChanged();
} catch (Exception e) {
// TODO: handle exception
}
lv.invalidate();
lv.setAdapter(adapter);
lv.invalidate();

yaa.. there default text is HEllo world.. bt removing it.. makes text
view null at those postions where hello world was coming.
Ok. So i guess it might be due to "substringtwo" object returning null. Can you try moving
holder.messageLeftPart.setText(substringtwo);
into below if block
//Check for not string object null and non empty and not containing string value null
if(!TextUtils.isEmpty(substringtwo) && !substringtwo.equalsIgnoreCase("null")) {
//set message text here
}
OR
try initializing variable substringtwo to empty string i.e. String substringtwo = "";

Related

ListView adds duplicates of itself when changing the mode to light/dark

I have a problem with my android app for making notes. When I change mode (in app) from default to dark or light, the list duplicate itself. I have a custom adapter for ListView:
public View getView(int position, View listView, ViewGroup parent) {
View v = listView;
TextView tvTitle;
TextView tvContent;
Note n = noteList.get(position);
Set<String> folders = n.getFolders();
Set<String> foldersForChips = new HashSet<>(folders);
foldersForChips.remove("Notes");
foldersForChips.remove("All Notes");
NoteHolder holder = new NoteHolder();
if (listView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.row_layout, null);
// view of the labels of the note ------------------------------------------------------
holder.foldersChipGroup = (ChipGroup) v.findViewById(R.id.labels_of_note);
holder.foldersChipGroup.setChipSpacingHorizontal(2);
holder.foldersChipGroup.setClickable(false);
holder.foldersChipGroup.setFocusable(false);
for (String folder : foldersForChips) {
Chip folderChip = new Chip(context);
folderChip.setText(folder);
folderChip.setTextSize(8);
folderChip.setEnsureMinTouchTargetSize(false);
folderChip.setHeight(40);
folderChip.setChipMinHeight(10);
folderChip.setBackgroundColor(Color.TRANSPARENT);
folderChip.setChipBackgroundColor(null);
ChipDrawable chipFolderDrawable = ChipDrawable.createFromAttributes(context, null,0, R.style.Widget_App_Chip);
folderChip.setChipDrawable(chipFolderDrawable);
holder.foldersChipGroup.addView(folderChip);
}
tvTitle = (TextView) v.findViewById(R.id.title);
tvContent = (TextView) v.findViewById(R.id.content);
holder.titleView = tvTitle;
holder.contentView = tvContent;
v.setTag(holder);
} else {
holder = (NoteHolder) v.getTag();
}
// view of the title and content of the note -----------------------------------------------
if (n.getTitle() == "" || n.getTitle().isEmpty() || n.getTitle() == null ) {
holder.contentView.setVisibility(View.VISIBLE);
holder.contentView.setText(n.getContent());
holder.contentView.setPadding(20,0,20, 0);
} else if (n.getContent() == "" || n.getContent().isEmpty() || n.getContent() == null){
holder.titleView.setVisibility(View.VISIBLE);
holder.titleView.setText(n.getTitle());
holder.titleView.setPadding(20,0,20, 0);
} else {
holder.titleView.setVisibility(View.VISIBLE);
holder.titleView.setText(n.getTitle());
holder.titleView.setPadding(20,0,20, 0);
holder.contentView.setVisibility(View.VISIBLE);
holder.contentView.setText(n.getContent());
holder.contentView.setPadding(20,0,20, 0);
}
// background color ------------------------------------------------------------------------
holder.cardView = v.findViewById(R.id.cardView);
if (getItem(position).getBackgroundColor() != null) {
holder.cardView.setCardBackgroundColor(Color.parseColor(getItem(position).getBackgroundColor()));
}
return v;
}
the button which change the mode in MainActivity.java:
FloatingActionButton fabLight = findViewById(R.id.light);
fabLight.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
themeChange.setVisibility(View.VISIBLE);
SharedPreferences settingsPreferences = getApplicationContext().getSharedPreferences("com.example.settings", Context.MODE_PRIVATE);
settingsPreferences.edit().putInt("Mode", AppCompatDelegate.MODE_NIGHT_NO).apply();
listView.refreshDrawableState();
noteAdapter.notifyDataSetChanged();
//listView.setAdapter(noteAdapter);
}
});
I found similar problem: ListView Added Duplicate item in list when screen orientation changes, but unfortunaltely the answers does not help me - I do not know how to implement them. I am new with android and I will be grateful for some guidance.
I tried refreshDrawableState() and setAdapter(noteAdapter) on my listView and notifyDataSetChanged() on adapter but it does not help. It is probable that I implement getView or my list in it wrong but I do not know how to improve that.
Thank you in advance for all help.
In case - all files are in my GitHub repository:
https://github.com/wmaterkowska/MyNotes_app.git
(My polish answer has been deleted so changed it to English)
Method onCreate() is evoked when activity is launched first time, but also after screen configuration changes (and in some other situations) - for instance orientation or as in your case theme. There is no guarantee that this method will be called only single time, so if you create a list in here you should clear it to avoid duplication of the content every time method is called.
notesToShow.clear(); //Add a line here
for (Note note : allNotes) {
if (note.getFolders().contains(folder) && !note.getFolders().contains("Recycle Bin")) {
notesToShow.add(note);
}
}
Hope it helps!

How could I know which "TextView" is clicked

I was creating a dynamic Text View and I need to know which one of those Text views was clicked by the user i read that i need to use getTag() method but it keeps return null when i try it this is my activity code in java:
for(int i=0;i<size;i++){
TextView temp = new TextView(this);
temp.setId(i);
temp.setId(i);
String s = "";
temp.setText(s);
temp.setTextColor(Color.RED);
mylieniarlayout.addView(temp);
tv[i] = temp;
}
final TextView answertv = findViewById(R.id.answertv);
mylieniarlayout.setOnClickListener(new View.OnClickListener() {
#SuppressLint("SetTextI18n")
#Override
public void onClick(View v) {
Toast.makeText(getBaseContext(),"ID: "+ v.getTag(), Toast.LENGTH_SHORT).show();
answertv.setText("Clicked ID: " + v.getTag());
}
});
Firstly, setTag() and getTag() methods on view are not used for identifying the view. We use getId() for identifying the view. Please read document here,
getTag on android developers
Secondly, your onClickListner is on layout which won't give you the selected id of textView. In your code you are setting an ID for the text view and trying to fetch a tag which is a mistake.
onClickListener should be on the textview of which you want a tag.
While creating a textView set the tag and then you will get the tag for that textview.
You can try if else condition
Like:
if(v.getTag() == 0){
//Show position 0 here
} else {
//Other position
}
Hope you got your answer

Changing text color in Listview using SimpleCursorAdapter.ViewBinder

I've listed the names from database using SimpleCursorAdapter and I want to change the color of a particular name using SimpleCursorAdapter.ViewBinder's method. I've a problem while running this method, my database contains different names but the ListView will display all the namse as one particular name. What am I doing wrong? How to change the text color of a specific name? Is it possible using ViewBinder?
This is my part of of code for ViewBinder:
SimpleCursorAdapter.ViewBinder binder = new SimpleCursorAdapter.ViewBinder() {
#Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
// TODO Auto-generated method stub
String[] temp = dh.return_result();
tv = (TextView)findViewById(R.id.textView1);
tv = (TextView) view;
for(int i = 0; i<temp.length; i++)
{
if(temp[i].equalsIgnoreCase("Ameer Zhann"))
{
tv.setText(temp[i]);
tv.setTextColor(Color.rgb(58, 58, 224));
return true;
}
}
return false;
}
};
and this is my output image:
How can I solve this?
Try this way:
public boolean setViewValue(View view, Cursor cursor, int columnIndex){
int getIndex = cursor.getColumnIndex("Name");
String empname = cursor.getString(getIndex);
tv = (TextView) view;
tv.setTextColor(Color.WHITE);
tv.setText(empname);
if(empname.equals("Any String"))
{
tv.setTextColor(Color.rgb(58, 58, 224));
return true;
}
return false;
}
Code do exactly what you ask - for every element in Cursor you go through all list and set text of each element. I think that "Ameer Zhann" is last result in your list, so only this text left in TextView.
Method setViewValue(...) called for every element of Cursor. So, you don't need any cycle, just fill text with cursor value tv.setText(Cursor.getString(...));.
Also there is something strange with this code:
tv = (TextView)findViewById(R.id.textView1);
tv = (TextView) view;
view that comes as param - is already view with id R.id.textView1 - so just remove call of findViewById.
try with the else part
if(temp[i].equalsIgnoreCase("Ameer Zhann")){
tv.setText(temp[i]);
tv.setTextColor(Color.rgb(58, 58, 224));
}else{
tv.setText(temp[i]);
}
and at the end return true instead of false

Duplicated layout reference in list view

There is an really weird thing happening with my listview. I am creating an ListView with buttons and an editText.
It's disposed like this: [Button] [EditText] [Button], The buttons works like an "incrementer" and "decrementer" updating the numerical value of EditText in 1 unit per click.
The problem is, when I click in an button, almost every time an editText of another list view element is changed (the editText of the clicked item is also changed). And if I click in a button of this erroneous changed item, it also changes the editText of the first one. They basically have the same reference of buttons and editText, although they have textViews with data, and this data is different between they.
To accomplish that I created and custom adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = mInflater.inflate(R.layout.lastproduct_row, null);
holder = new ViewHolder();
holder.btnAddQtd = (Button) convertView.findViewById(R.lastproduct_row.btn_add_qtd);
holder.btnSubQtd = (Button) convertView.findViewById(R.lastproduct_row.btn_sub_qtd);
holder.etQuantidade = (EditText) convertView.findViewById(R.lastproduct_row.et_quantidade);
TextView tv;
holder.tvList = new TextView[PRODUCTROW_INT_KEY.length];
for(int i = 0; i < PRODUCTROW_INT_KEY.length; i++) {
tv = (TextView) convertView.findViewById(PRODUCTROW_INT_KEY[i]);
holder.tvList[i] = tv;
}
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
HashMap<String, String> hm = productsList.get(position);
String key = hm.get(CODIGO_KEY);
for(int i = 0; i < PRODUCTROW_INT_KEY.length; i++) {
holder.tvList[i].setText(hm.get(PRODUCTROW_STR_KEY[i]));
}
holder.btnAddQtd.setTag(key+QTD_FLAG+ADD_ACTION);
holder.btnSubQtd.setTag(key+QTD_FLAG+SUB_ACTION);
holder.btnAddQtd.setOnClickListener(handle);
holder.btnSubQtd.setOnClickListener(handle);
if(novosEstoques.containsKey(key)) {
holder.etQuantidade.setText(MyParseFunctions.parseCentesimal(novosEstoques.get(key).getQuantidade()));
}
return convertView;
}
class ViewHolder {
private TextView []tvList;
private Button btnAddQtd, btnSubQtd;
private Button btnAddQtVol, btnSubQtVol;
private EditText etQuantidade, etQtVolume;
}
I added onClick listenners to the buttons, setting their tags with my listView element ID (concatenated with another informations). Then in my event listener I just get the button parent View (an LinearLayout) and get the EditText from that using getViewAt():
#Override
public void onClick(View v) {
String tag = (String) v.getTag();
if(tag.contains(QTD_FLAG)) {
String []info = ((String) v.getTag()).split(QTD_FLAG);
float qtd;
LinearLayout ll = (LinearLayout) v.getParent();
ll.setBackgroundColor(Color.rgb(0, 128, 30));
EditText et = (EditText) ll.getChildAt(2);
qtd = Float.parseFloat(et.getText().toString().replace(",", "."));
if(info[1].equals(ADD_ACTION)) {
qtd++;
}
else if(info[1].equals(SUB_ACTION)) {
if(qtd > 0)
qtd--;
}
Log.d("TESTE", "MODIFICAR KEY = "+info[0]);
et.setText(qtd+"");
}
}
I'm using an setBackgroundColor in this example to confirm that the LinearLayout instance is duplicated in the lisView. When I click an Button, it's painted in 2 different list view item.
Anyone can point me what could be doing this? I have found people with an duplicated ListView item, I don know if that is my case, cause I have TextView's inside my ListView, and they are not equal, only the LinearLayout portion with buttons and editText is "shared".
I make some changes in my getView method and it's working now! It seems that every time the getView method is called i have not guarantee at all that my editTexts will be filled properly and I didn't realize that. So every getView call I make I set the editText value, if the user edit an ET value, I store it in a HashMap to restore in getView, if there is no entry in HashMap for the given editText, then I set it to the default value (zero):
...
if(convertView == null) {
holder = new ViewHolder();
holder.btnAddQtd = (Button) convertView.findViewById(R.lastproduct_row.btn_add_qtd);
holder.btnSubQtd = (Button) convertView.findViewById(R.lastproduct_row.btn_sub_qtd);
holder.etQuantidade = (EditText) convertView.findViewById(R.lastproduct_row.et_quantidade);
//Now it is easier to get etQuantidade reference in button
//click handle, I just have to do:
// public onClick(View v) {
// EditText etButtonAssociated = (EditText) v.getTag();
// ...
// }
holder.btnAddQtd.setTag(holder.etQuantidade);
holder.btnSubQtd.setTag(holder.etQuantidade);
holder.btnAddQtd.setOnClickListener(handle);
holder.btnSubQtd.setOnClickListener(handle);
...
}
else {
...
}
holder.etQuantidade.setTag(key);
if(novosEstoques.containsKey(key)) {
holder.etQuantidade.setText(MyParseFunctions.parseCentesimal(novosEstoques.get(key).getQuantidade()));
}
else {
holder.etQuantidade.setText("0");
}
return convertView;
Israel,
After looking over your code, I was wondering about an implementation decision you have made. Since each Button is "bound" to a particular EditText, have you considered setting the Tag of those Buttons to the EditText? The Tag may be any Object including a UI element. This is especially useful for dynamic UI elements, such as a runtime populated list.
Since this is handled in your Adapter you wouldn't have to worry about duplicate Parents and such. Additionally, you could avoid having to worry about "finding" the control in your onClick() because you would have it (It's the tag). I'm not sure exactly what your project needs are, but this seems like a potentially viable solution, unless you need those Buttons to accomplish other tasks.
Note of Caution
Just make sure that you erase the Tags' references to the EditText when you are done. Otherwise, you run the risk of leaking some memory.
FuzzicalLogic

Last item click null pointer excepction

listView=(ListView)findViewById(R.id.list);
listView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View viewItem, int position, long arg3) {
if(!itemClicked)
{
viewItem = parent.getChildAt(position);
((Button)viewItem.findViewById(R.id.gov)).setVisibility(View.VISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
itemClicked=true;
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}
else
{
viewItem=parent.getChildAt(clickedItemPos);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.INVISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.INVISIBLE);
viewItem = parent.getChildAt(position);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.VISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}
final int[] coordAndCat = FavoriteCoord(ime.toString());
Nullpointer exception happens when I have more elements and when you scroll and click the last item on the listview. How to workaround this?
Note: I'm trying to display 2 buttons in every item that is being clicked. This code works for all clicks on items besides the last one (if there are many elements in the list and you need to scroll)
clickedItemPos isn't defined after else unless clickedItemPos=position has been called earlier. What line does the error happen on?
listView=(ListView)findViewById(R.id.list);
listView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View viewItem, int position, long arg3) {
if(!itemClicked)
{
viewItem = parent.getChildAt(position);
//start >> This might be where your problem is (R.id.gov)
((Button)viewItem.findViewById(R.id.gov)).setVisibility(View.VISIBLE);
//end <<
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
itemClicked=true;
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}
else
{
viewItem=parent.getChildAt(clickedItemPos);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.INVISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.INVISIBLE);
viewItem = parent.getChildAt(position);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.VISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}
final int[] coordAndCat = FavoriteCoord(ime.toString());
I think you said R.id.gov instead of R.id.go unless R.id.gov is truly an id you have. That is the only thing I saw 'wrong', please show a stacktrace for the error next time, it would help in debugging =)
EDIT
is clickedItemPos initialized somewhere else? because if it isn't this line: viewItem=parent.getChildAt(clickedItemPos); in your else statement would probably be null if nothing was selected before. I understand you want to use this in order to check for previously clicked items, but if nothing was clicked before, this will never get set to a value and therefore be null try doing this in that else statement to avoid the possible null variable:
else
{
if(clickedItemPos != null){ //only add this if there was a previous clicked item
viewItem=parent.getChildAt(clickedItemPos);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.INVISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.INVISIBLE);
viewItem = parent.getChildAt(position);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.VISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}else{
viewItem = parent.getChildAt(position);
((Button)viewItem.findViewById(R.id.go)).setVisibility(View.VISIBLE);
((Button)viewItem.findViewById(R.id.re)).setVisibility(View.VISIBLE);
viewItem.invalidate();
clickedItemPos=position;
TextView text = (TextView)viewItem.findViewById(R.id.item);
ime = text.getText();
}
}
hopefully that will fix it. In your stack trace it says line 91 in your class is the line causing the error, what variable is located on that line? that is usually a good indicator of what variable is causing the null pointer, but since we don't know the line numbers for your code it is hard to guess where the issue is.
Yes there is repeated code in that solution but you could always make a method to put the repeated code in and call that instead if you want.
Good Luck, hope this helps.

Categories

Resources