I can't seem to figure out why my list row item won't change color:
/** Populate the Views in act_alliances.xml with data from the database */
private void loadAllianceData() {
TblAlliances mTAlliances = new TblAlliances(this);
mTAlliances.openRead();
Cursor mCursor = mTAlliances.selectSectorData(mSector);
// load Sector Name into act_alliance_detail.xml
TextView mTxtSctName = (TextView) findViewById(R.id.allc_sname);
mTxtSctName.setText("Sector: "+mSector);
// load the "Number of Alliances" field with the count from the cursor
TextView mTxtNumAllcs = (TextView) findViewById(R.id.allc_textView2);
mTxtNumAllcs.setText(String.valueOf(mCursor.getCount()));
String[] cols = new String[] {
mTAlliances.C_FID,
mTAlliances.C_FANAME,
mTAlliances.C_FPLTC,
mTAlliances.C_FSPWER
};
int[] to = new int[] {
R.id.allc_lstRow_textView1,
R.id.allc_lstRow_textView2,
R.id.allc_lstRow_invisible,
R.id.allc_lstRow_textView3
};
// connect to the ListView and clear it just in case this isnt the first time
ListView mListView = (ListView) findViewById(R.id.allc_listView);
mListView.destroyDrawingCache();
mListView.setVisibility(ListView.INVISIBLE);
mListView.setVisibility(ListView.VISIBLE);
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
SimpleCursorAdapter dataAdapter = new SimpleCursorAdapter(
this,
R.layout.act_alliances_list_row,
mCursor,
cols,
to,
0);
dataAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
#Override
public boolean setViewValue(View view, Cursor cursor, int column) {
if( column == 1 ){
TextView tv = (TextView) view;
String mPltc = cursor.getString(cursor.getColumnIndex("FPLTC"));
if (BuildConfig.DEBUG) {
Log.i(Constants.TAG_ACTALLIANCES, "loadAllianceData(): Political Relation: "+mPltc);
}
// Set color of item based on Political Relation
if(mPltc == "Ally"){tv.setTextColor(Color.parseColor("#6699ff"));}
if(mPltc == "Vassal"){tv.setTextColor(Color.parseColor("#00ff00"));}
if(mPltc == "Enemy"){tv.setTextColor(Color.parseColor("#ff0000"));}
return true;
}
return false;
}
});
// Assign adapter to ListView
mListView.setAdapter(dataAdapter);
mListView.setOnItemClickListener( new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// selected item
mAllianceForDetail = ((TextView) arg1.findViewById(R.id.allc_lstRow_textView2)).getText().toString();
startAct("AllianceDetail");
}
});
mTAlliances.close();
}
Everything in the SimpleCursorAdapter.ViewBinder seems to be in order, but the color won't change...i suspect that it may be WHERE i placed the ViewBinder more than the ViewBinder itself.
Any help would be appreciated!
You can't equalize object with a string. You need to use equals or equalsIgnoreCase functions
if (mPltc.equalsIgnoreCase("Ally")){tv.setTextColor(Color.parseColor("#6699ff"));}
if (mPltc.equalsIgnoreCase("Vassal")){tv.setTextColor(Color.parseColor("#00ff00"));}
if (mPltc.equalsIgnoreCase("Enemy")){tv.setTextColor(Color.parseColor("#ff0000"));}
return true;
Try using
if(mPltc.equals("Ally"))...
instead of
if(mPltc == "Ally")
(Same with "Vassal", "Enemy", etc)
You shouldn't use == on String objects, as it doesn't work the way you'd expect.
Related
I am working on a project where I have a let's say 5x5 grid of TextViews and I want to check if an entire row or column has equal elements. I am using an Adapter class to inflate my gridview with simply one textview element. Here is the code that I have tried but I cannot seem to make it work:
final int size = gridView.getCount(); //25
int temp = 0;
for (int i = 0; i < size; i++) {
ViewGroup gridChild = (ViewGroup) gridView.getChildAt(i);
childSize = gridChild.getChildCount();
for (int j = 0; j < childSize; j++) {
if (gridChild.getChildAt(j) instanceof TextView &&
((TextView) gridChild.getChildAt(j)).getText().toString().equals("x")) {
temp++;
}
The thing is when i tried to debug, debugger showed null values for childSize variable and could not properly get the value from getChildAt. Basically, what I am trying to do is get inside the if statement. Also this is the first time I am working with ViewGroup calss, and the methods that I call. Any help would be appreciated.
Edit:I am looking for a way to do this outside the getView method in the adapter class and not in a onClick method as well. (Code sample answers would be highly appreciated). Also, the getChildAt method call returns null so the code I have shown would not work because I am assigning a null value to the gridChild.
This is the onClick that I use for the TextViews:
`
public void numberFill(View view) {
if (((TextView) view).getText().toString().isEmpty()) {
((TextView) view).setText(String.valueOf(numbCounter + 1));
numbCounter++;
}
else if (!((TextView) view).getText().toString().isEmpty() && numbCounter >= 16) {
((TextView) view).setText("x");
}
}
This is my adapter class:
public class GridAdapter extends BaseAdapter {
private final Context mContext;
private String[] numbers;
public GridAdapter(Context context, String[] numbers) {
this.mContext = context;
this.numbers = numbers;
}
#Override
public int getCount() {
return numbers.length;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public Object getItem(int position) {
return numbers[position];
//return null;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater)
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(mContext);
gridView = inflater.inflate(R.layout.textview_layout, null);
TextView textView = (TextView) gridView.findViewById(R.id.cell);
textView.setText(numbers[position]);
} else {
gridView = (View) convertView;
}
return gridView;
}
}
numberFill reworked:
public void numberFill(View view) {
int index = (Integer) view.getTag();
if (numbers[index].toString().isEmpty()) {
numbers[index] = String.valueOf(numbCounter + 1);
numbCounter++;
}
else if (!numbers[index].toString().isEmpty() && numbCounter >= 25) {
numbers[index] = "x";
}
gridAdapter.notifyDataSetChanged();
}
`
When using an AdapterView – such as your GridView – you generally don't want to directly access and manipulate its child Views outside of its Adapter. Instead, the dataset backing the Adapter should be updated, and the GridView then refreshed.
In your case, you presumably have a setup similar to this in your Activity:
private GridAdapter gridAdapter;
private String[] numbers;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
numbers = new String[25];
gridAdapter = new GridAdapter(this, numbers);
}
Here, the numbers array is what you want to directly modify, rather than the text on the GridView's child TextViews. That array is then easily iterated over to do your row and column value checks.
Since the array will be modified in the Activity, we need a way to pass the clicked TextView's position in the Adapter to the Activity's click method, as we'll need it to access the correct array element. For this, we can utilize the tag property available on all View's, via the setTag() and getTag() methods. For example, in GridAdapter's getView() method:
...
TextView textView = (TextView) gridView.findViewById(R.id.cell);
textView.setText(numbers[position]);
textView.setTag(position);
...
In the click method, the position can be easily retrieved with getTag(), and used as the index to get the clicked TextView's text from the numbers array. You can then do the necessary processing or calculation with that text, set the modified value back to the array element, and trigger a refresh on the Adapter.
public void numberFill(View view) {
int index = (Integer) view.getTag();
// Do your processing with numbers[index]
numbers[index] = "new value";
gridAdapter.notifyDataSetChanged();
}
The notifyDataSetChanged() call will cause the GridView to update its children, and your new value will be set in the appropriate TextView. The numbers array now also has the current values, and is readily available in the Activity to perform the necessary checks there.
Hello I have a problwm witch Listview.
I use listview for show items in list.
I have activity where is Listview. And If I longpress on row in listview open popup (dialog) where I can edit word in row.
If edit finish I Call this
AddItemInPacage.obnovitem=true;
AddItemInPacage.indexitem=poz;
AddItemInPacage.novyitem=novypacage;
Boolean is for Timer if is true Start This method
public void ZmenItem(int indexzmeny,String nove) {
ListAdapter.clear();
for (int i=1;i<prvy.getPacageItem2(indexpacage)+1;i++) {
ListAdapter.add(String.valueOf(prvy.citajItem(indexpacage,i)));
}
ListAdapter.set(indexzmeny,nove);
Toast.makeText(this, "citam "+ ListAdapter.get(indexzmeny), Toast.LENGTH_SHORT).show();
thadapter = new MyThumbnailAdapter(getApplication(), R.layout.list_row, ListAdapter);
List.setAdapter(thadapter);
thadapter.notifyDataSetChanged();
}
Everything is OK when I while I not open the same row. If edited row for some times in row Program not work good.
Everything is good while this line List.setAdapter(thadapter); after thise line is Variables good too, but listview in display not rewrite.
Why?
I have three times this List.setAdapter(thadapter); on program but on OnCreate method and when Put new row in listview... So when Edited row I call only thise method ↑↑ which sometimes rewrite good and sometimes not.
Because Thise program isn't it 100% good :(
ListView List;
MyThumbnailAdapter thadapter = null;
ArrayList<String> ListAdapter = new ArrayList<String>();
This is my Adapter
public class MyThumbnailAdapter extends ArrayAdapter<String> {
ArrayList<String> arr;
private TextView text;
public MyThumbnailAdapter(Context context, int textViewResourceId, ArrayList<String> objects) {
super(context, textViewResourceId, objects);
this.arr = objects;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
LayoutInflater inflater = getLayoutInflater();
view = inflater.inflate(R.layout.list_row, parent, false);
TextView textnumber = (TextView) view.findViewById(R.id.text);
ImageView delButton = (ImageView) view.findViewById(R.id.btn_del);
Typeface robtoLight = Typeface.createFromAsset(getContext().getAssets(), "fonts/Roboto-Light.ttf");
textnumber.setTypeface(robtoLight);
delButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
arr.remove(position);
thadapter.notifyDataSetChanged();
Toast.makeText(getContext(), "Item deleted", Toast.LENGTH_SHORT).show();
}
});
textnumber.setText(arr.get(position));
textnumber.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
for (int i=ListAdapter.size()-1;i>=0;i--) {
// for (int i = 0; i < ListAdapter.size() ; i++) {
try {
prvy.pridajItemRemove(ListAdapter.get(i), indexpacage, i+1);
} catch(IndexOutOfBoundsException e) {
prvy.Nulak(indexpacage,i);
}
}
prvy.setPacageItem2(ListAdapter.size(),indexpacage);
prvy.setPocItem(ListAdapter.size());
for (int i=ListAdapter.size();i<99;i++) {
prvy.Nulak(indexpacage,i+1);
}
Serializuj(prvy,nazovtripu);
EditItemDialog cdd=new EditItemDialog(AddItemInPacage.this,nazovtripu,position,indexpacage);
cdd.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
cdd.show();
return true;
}
});
return view;
}
}
I put picture
Sometimes if I edit row Toas read good string, but Listview no rewrite.
This may help you
ListAdapter.notifyDataSetChanged()
Hoping ListAdapter is name of your adapter
I need synchronized confirm edit in Dialog with medhod which rewrite Listview.
Or switch sequence from
AddItemInPacage.obnovitem=true;
AddItemInPacage.indexitem=poz;
AddItemInPacage.novyitem=novypacage;
to
AddItemInPacage.indexitem=poz;
AddItemInPacage.novyitem=novypacage;
AddItemInPacage.obnovitem=true;
Because If AddItemInPacage.obnovitem=true; first Activity work with old information in variable novypacage. And when variable novypacage is full from dialog. Listview finish work with old information in this variable.
I can't find an answer to delete in a listview created using SimpleCursorAdapter
So i make this listview in a fragment, here's the code
final Cursor cursor = myDb.cautarevenituri();
// The desired columns to be bound
final String[] columns = new String[] {
DatabaseHelper.COL_2,
DatabaseHelper.COL_3
};
int[] toviewids = new int[] { R.id.nume_item,R.id.valoare_item};
dataAdapter = new SimpleCursorAdapter(getActivity().getBaseContext(),R.layout.item_layout,cursor,columns,toviewids,0);
//
final ListView listView = (ListView)getView().findViewById(R.id.listView_venituri);
listView.setAdapter(dataAdapter);
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long arg3) {
Toast.makeText(getActivity(), " " + position, Toast.LENGTH_LONG).show();
//delete from listview in database and listview too??
//
//
return false;
}
});
Thank you.
Delete from Database and refresh the listview.
You have to update your list that you passed into the adapter and then call adapter.notifyDataSetChanged()
Use the swapCursor() method to update the data inside a SimpleCursorAdapter:
myDb.getWriteableDatabase().delete(TABLE_NAME, KEY_ID + "=?", position);
Cursor newCursor = myDb.getReadableDatabase().query(**etc.**);
dataAdapter.swapCursor(newCursor);
I created the following CursorAdapter which shows messages from my SQL database, everything is added well until I scroll the list, I know that the objects are recycled, but in a wrong way. Here is my CursorAdapter class:
public class ChatAdapter extends CursorAdapter {
public ChatAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.chat_item, parent,
false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Find fields to populate in inflated template
TextView left = (TextView) view.findViewById(R.id.lefttext);
TextView right = (TextView) view.findViewById(R.id.righttext);
LinearLayout rightBubble = (LinearLayout) view
.findViewById(R.id.right_bubble);
LinearLayout leftBubble = (LinearLayout) view
.findViewById(R.id.left_bubble);
TextView leftDate = (TextView) view.findViewById(R.id.leftdate);
TextView rightDate = (TextView) view.findViewById(R.id.rightdate);
// Extract properties from cursor
String from = cursor.getString(cursor.getColumnIndexOrThrow("from"));
String txt = cursor.getString(cursor.getColumnIndexOrThrow("message"));
String date = cursor.getString(cursor.getColumnIndexOrThrow("t"));
String id = cursor.getString(cursor.getColumnIndexOrThrow("id"));
// Parse time
long datevalue = Long.valueOf(date) * 1000;
Date dateformat = new java.util.Date(datevalue);
String convert = new SimpleDateFormat("HH:mm").format(dateformat);
// Populate fields with extracted properties
if (from.equals("me")) {
right.setText(txt);
left.setText("");
rightBubble
.setBackgroundResource(R.drawable.balloon_outgoing_normal);
leftBubble.setBackgroundDrawable(null);
rightDate.setText(convert);
leftDate.setVisibility(View.GONE);
}
else {
left.setText(txt);
right.setText("");
leftBubble
.setBackgroundResource(R.drawable.balloon_incoming_normal);
rightBubble.setBackgroundDrawable(null);
leftDate.setText(convert);
rightDate.setVisibility(View.GONE);
}
}
}
Unfortenately, after scrolling the list, dates from the rightDate and leftDate dissapears after moving back. I think it't due the .setVisibility(View.GONE)
Any suggestions to fix this?
when the view is recycled, it is in the previous state, android did not clear the status for you.
To fix your problem, you have to set the view in question to VISIBLE when needed
Edit:
like this, add the 2 lines
if (from.equals("me")) {
// your original code
rightDate.setVisibility(View.VISIBLE); //add this
}
else {
// your original code
leftDate.setVisibility(View.VISIBLE); //add this
}
I have an app that gathers points from checkboxes in a listview. The checkboxes are dynamically added along with the items of the listview. Each time a checkbox is clicked, I add points to a total. The manner in which I do this works fine as long as all the list items fit on the screen. When the list gets long enough to cause it to scroll, I lose the values I had previously checked when I scroll down the list. So, my scrolling the list causes the points to reset. I feel pretty confident it has something to do with losing focus from the checkboxes and/or gaining focus from the click to the listview itself, that causes this reset in points.
IMPORTANT EDIT: Ok, so it doesn't actually take a simple click and SLIGHT scroll of the listview to cause this to happen. I have to actually get the previous CHECKBOX scrolled out of view just enough to make the points reset. WTF?
Here's some code...
Here is my entire custom adaptor that handles the checkbox:
public class ScoreListAdapter extends BaseAdapter {
private ArrayList<ScoringInfo> data;
Context c;
ScoringInfo scr;
ScoreListAdapter (ArrayList<ScoringInfo> data, Context c){
this.data = data;
this.c = c;
}
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
public Object getItem(int pos) {
// TODO Auto-generated method stub
return data.get(pos);
}
public long getItemId(int pos) {
// TODO Auto-generated method stub
return pos;
}
public View getView(int pos, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = convertView;
if (v == null)
{
LayoutInflater vi = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.score_list_row, null);
}
TextView subtaskView = (TextView)v.findViewById(R.id.subtask);
TextView maxPointsView = (TextView)v.findViewById(R.id.max_points);
scr = data.get(pos);
subtaskView.setText(scr.subtask);
maxPointsView.setText("Points: " + Integer.toString(scr.maxPoints));
final CheckBox checkBox = (CheckBox) v.findViewById(R.id.score_box);
checkBox.setTag(R.string.subtask_num, scr.subtaskNum);
checkBox.setTag(R.string.score, scr.maxPoints);
checkBox.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int subNum = Integer.parseInt(checkBox.getTag(R.string.subtask_num).toString());
int score = (Integer) checkBox.getTag(R.string.score);
if (((CheckBox)v).isChecked()) {
score =(Integer) checkBox.getTag(R.string.score);
Challenge.subtaskScores.put(subNum, score);
scr.addToTotalPoints(score);
updatePoints(scr.getTotalPoints());
}
else {
if (Challenge.subtaskScores.containsKey(subNum))
Challenge.subtaskScores.remove(subNum);
scr.addToTotalPoints(-score);
updatePoints(scr.getTotalPoints());
}
}
});
return v;
}
public void updatePoints(int total){
TextView scrUpdate = (TextView) ((Activity)c).findViewById(R.id.curr_score_view);
Challenge.totalPoints1 = total;
int grandTotal = Challenge.totalPoints1 + Challenge.totalPoints2;
scrUpdate.setText("Current Score: " + grandTotal);
}
}
Here is what I feel is the relevant code from Challenge.class:
public void createScoringList() {
// Builds two lists: one for the tasks that do not allow partial points, and
// another for the tasks that DO allow partial points. The lists are stacked
// on top of each other. This was the only way I could come up with to present
// two types of layouts for the two types of point input. This may need to be
// reconsidered.
ListView scoreList = (ListView) findViewById(R.id.score_list);
ListView scoreListPartial = (ListView) findViewById(R.id.score_list_partial);
ArrayList<ScoringInfo> objList = new ArrayList<ScoringInfo>();
ArrayList<ScoringInfo> objListPartial = new ArrayList<ScoringInfo>();
ScoringInfo scrInfo;
// The ScoringInfo object holds the various fields that are associated with each subtask.
infoView = (TextView) findViewById(R.id.chall_team_config_show);
infoView.setText(chall_name + " (id: " + challenge_id + ")\nTeam: " + team_num +
"\nConfiguration: " + randomConfig);
for (int i = 0; i < subTaskList.size(); i++) {
subtask_num = subTaskList.get(i).subtask_num;
max_points = subTaskList.get(i).max_points;
partial_points_allowed = subTaskList.get(i).partial_points_allowed;
task_name = subTaskList.get(i).task_name;
scrInfo = new ScoringInfo();
scrInfo.setMaxPoints(max_points);
scrInfo.setSubtask(task_name);
scrInfo.setSubtaskNum(subtask_num);
if (partial_points_allowed == 1)
objListPartial.add(scrInfo);
else
objList.add(scrInfo);
}
// There is a custom adapter for both possible lists should the challenge need it.
scoreList.setAdapter(new ScoreListAdapter(objList , this));
scoreListPartial.setAdapter(new ScoreListAdapter2(objListPartial, this));
}
No doubt I forgot something. If there's confusion over my question, please ask for clarification. This is driving me nuts, and keeping me up all night.
Your problem is as stated by #Patrick on the first comment that your are not saving the CheckBox state. You will need to save it to somewhere, a boolean array for example.
Then when you recreate the view you will get the saved value from the array and check/uncheck the CheckBox.