ListView with custom adapter not getting updated - android

I want to update the list view whenever any item is updated or deleted.I have tried many options,but none of them is working.This is the code of the list view:
public class HelloBubblesActivity extends Activity {
private com.warting.bubbles.DiscussArrayAdapter adapter;
private ListView lv;
private LoremIpsum ipsum;
private EditText editText1;
private static Random random;
Runnable m_handlerTask;
TextView tv ;
LinearLayout ll;
Handler m_handler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_discuss);
lv = (ListView) findViewById(R.id.listView1);
adapter = new DiscussArrayAdapter(getApplicationContext(), R.layout.listitem_discuss);
lv.setAdapter(adapter);
ll = (LinearLayout)findViewById(R.id.wrapper);
m_handler = new Handler();
addItems();
ReduceTimeIteration();
}
public void ReduceTimeIteration()
{
adapter.clear();
((BaseAdapter) lv.getAdapter()).notifyDataSetChanged();
adapter.notifyDataSetChanged();
adapter.notifyDataSetInvalidated();
lv.invalidate();
lv.requestLayout();
Log.d("Adapter: ", "Adapter is changed");
}
private String addItems() {
String a = "Hello bubbles";
adapter.add(new OneComment(true,a));
return a;
}
}
This is the code of the custom adapter:
public class DiscussArrayAdapter extends ArrayAdapter<OneComment> {
private TextView countryName;
private List<OneComment> countries = new ArrayList<OneComment>();
private LinearLayout wrapper;
static View row ;
#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();
}
public OneComment getItem(int index) {
return this.countries.get(index);
}
public View getView(int position, View convertView, ViewGroup parent) {
row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.listitem_discuss, parent, false);
}
wrapper = (LinearLayout) row.findViewById(R.id.wrapper);
OneComment coment = getItem(position);
countryName = (TextView) row.findViewById(R.id.comment);
countryName.setText(coment.comment);
countryName.setBackgroundResource(coment.left ? R.drawable.bubble_yellow : R.drawable.bubble_green);
wrapper.setGravity(coment.left ? Gravity.LEFT : Gravity.RIGHT);
return row;
}
public Bitmap decodeToBitmap(byte[] decodedByte) {
return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
}
}
In the list view, i want to remove all the views using adapter.clear() and then want to update the list view.But even after calling adapter.clear() , the list view remains the same.Please help me. Thanks in advance.

I suggest you create you adapter in the following way:
// declared in activity
private List<OneComment> countries = new ArrayList<OneComment>();
// in onCreate()
adapter = new DiscussArrayAdapter(getApplicationContext(), R.layout.listitem_discuss, countries);
And then call countries.clear(); adapter.notifyDataSetChanged(); to clear the list view. Because you are basically using now your "countries" (list) to tell which size the adapter has, and which item to get upon that list.

Related

Android Java: Unable to selectively highlight rows in a ListView via onScroll listener

I have another blocker as I study Android Development.
This time my problem is when I wanted to "selectively" highlight a row in a ListView populated by data from an adapter.
This ListView is actually within a dialog, and purpose is to show a list of friends, where user can multi-select and highlight it as he selects.
The selected values by the way, is stored in an ArrayList "arr_FriendsShare" so that the next time he opens the listview, rows will be highlighted (via onScrollListener) for those previously selected.
What is currently happening, only the "recently" or "last" clicked row/item is highlighted; and seems to be clearing all the previously highlighted rows.
I cannot understand why it is behaving that way, as row's value is successfully stored to/removed from arr_FriendsShare ArrayList, as I click on it.
Below is my listener codes, and thanks in advance for the usual help:
//Item click listener for Select Friends ListView
listview_SelectFriends.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position,
long arg3)
{
String friends_ListItemSelected = (String)adapter.getItemAtPosition(position);
if(!arr_FriendsShare.contains(friends_ListItemSelected)){
arr_FriendsShare.add(friends_ListItemSelected);
}
else{
removeItemFromArrayListString(Main.this, arr_FriendsShare, friends_ListItemSelected);
}
}
});
listview_SelectFriends.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
for (int i = firstVisibleItem; i < (visibleItemCount + firstVisibleItem); i++) {
String listViewItemText = view.getItemAtPosition(i).toString();
if(arr_FriendsShare.contains(listViewItemText)){
ColorDrawable cd = new ColorDrawable(getResources().getColor(R.color.red_light));
view.setSelector(cd);
}
else if(arr_FriendsShare.contains(listViewItemText)){
ColorDrawable cd = new ColorDrawable(Color.TRANSPARENT);
view.setSelector(cd);
}
}
}
});
Additional Code Block:
ArrayList<String> stringArray = new ArrayList<String>();
String jsonURL = <SOME URL HERE>;
stringArray = Global.getStringArrayFromJSON(Main.this, jsonURL, "friends", "FriendUsername");
LayoutInflater inflater = getLayoutInflater();
View convertView = (View) inflater.inflate(R.layout.friends_list_layout, null);
ListView listview_SelectFriends = (ListView) convertView.findViewById(R.id.layout_Friends);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, stringArray);
listview_SelectFriends.setAdapter(adapter);
Change
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, stringArray);
to
// Define this at class level as --> private FriendsAdapter adapter = null;
adapter = new FriendsAdapter(Main.this, stringArray);
add this method in your activity
private void setResetSelection(int index, boolean setSelection){
View v = listview_SelectFriends.getChildAt(index);
if(v != null){
TextView name = (TextView) v.findViewById(R.id.name);
if(setSelection)
name.setBackgroundResource(R.color.red);
else
name.setBackgroundResource(R.color.transparent);
}
}
and create a new class as
public class FriendsAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private ArrayList<String> mFriends;
private ArrayList<String> mSelectedFriends = new ArrayList<String>();
public GoodPeopleAdapter(Context context, ArrayList<String> friends) {
mInflater = LayoutInflater.from(context);
mFriends= friends;
}
public void setSelectedFriends(ArrayList<String> selectedFriends){
mSelectedFriends = selectedFriends;
}
#Override
public int getCount() {
return mFriends.size();
}
#Override
public Object getItem(int position) {
return mFriends.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
ViewHolder holder;
if(convertView == null) {
view = mInflater.inflate(R.layout.row_layout, parent, false);
holder = new ViewHolder();
holder.name = (TextView)view.findViewById(R.id.name);
view.setTag(holder);
} else {
view = convertView;
holder = (ViewHolder)view.getTag();
}
String name = mFriends.get(position);
holder.name.setText(name);
if(mSelectedFriends.contains(name))
holder.name.setBackgroundResource(R.color.red) // red is in color xml by default, change according to your choice
return view;
}
private class ViewHolder {
public TextView name;
}
}
Add following line at the end of method onItemClick
adapter.setSelectedFriends(arr_FriendsShare);
Add this in the if part of onItemClick
setResetSelection(position, true);
and this in else part
setResetSelection(position, false);
Also create a new xml layout with name row_layout with a textview with id name.

Add item in listview arrayadapter

Please tell me how to add items in listview arrayadapter?
I found only how to make for standard adapter
Activity:
public class Activity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.m);
ListView lv=(ListView) findViewById(R.id.lv);
String[] Id1={"1","2","3"}, Text1={"one","two","three"};
CustomAdapter ad = new CustomAdapter(this, Id1 , Text1);
ad.setCustomListener(new LVListener() {
public void onClick(String text) {
Log.d("APP", text);
}
});
lv.setAdapter(ad);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
btn.setVisibility(View.GONE);
String[] Id2={"4","5","6"},Text2={"four","five","six"};
// add Id2 and Text2 in listview
}
});
}
}
CustomAdapter:
public class CustomAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] id, text;
private ListViewListener micl;
public CustomAdapter(Context context, String[] id, String[] text) {
super(context, R.layout.list, id);
this.context = context;
this.id = id;
this.text = text;
}
public void setCustomListener(ListViewListener micl) { this.micl = micl; }
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View View = inflater.inflate(R.layout.list, parent, false);
final int pos = position;
final TextView tView = (TextView) View.findViewById(R.id.textView);
tView.setText(text[pos]);
rowView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (micl != null)
micl.onClick(text[pos]);
}
});
return View;
}
}
I tried to do with notifyDatasetChanged() but nothing happened.
Please tell me how to do that.
ArrayAdapter has the add method, but in order to use it the dataset you provide to the super can not be an array, that's because the using Arrays.asList(objects), that returns an immutable list. From the documentation
Returns a List of the objects in the specified array. The size of the
List cannot be modified, i.e. adding and removing are unsupported, but
the elements can be set. Setting an element modifies the underlying
array.

Why do I have to scroll to refresh my list view?

I'm new to android. I'm trying to get my list view to update, I've tried everything...from calling notifydatasetchanged on the ui thread to just simply recreating my list adapter but for whatever reason when I update, no matter which method I use I have to scroll to see the changes. By this I mean that the data updates (say 13:01 changes to 13:02 in the list), it will update, but to see the change I have to scroll so that 13:01 goes off screen and then move back and it will have updated visually.
Why is this? (I can't post code right now as I'm on my phone but if required I will post later.)
EDIT: Here's the relevant code...sorry it took so long I haven't been at my computer for a couple of days.
Relevant parts of ListFragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.match_fragment, container, false);
}
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
MatchAdapter adapter = (MatchAdapter) this.getListAdapter();
if(futureMatches)
adapter = new MatchAdapter (this.getActivity(), ((MainActivity)this.getActivity()).getMatches(), futureMatches);
else
adapter = new MatchAdapter (this.getActivity(), ((MainActivity)this.getActivity()).getPastMatches(), futureMatches);
setListAdapter(adapter);
}
public void refresh()
{
MatchAdapter adapter;
//Update array in mainactivity
if(futureMatches)
MainActivity.refreshMatches((MainActivity) getActivity());
else
MainActivity.refreshPastMatches((MainActivity) getActivity());
//put updated entries in the adapter
if(futureMatches)
adapter = new MatchAdapter (getActivity(), ((MainActivity)getActivity()).getMatches(), futureMatches);
else
adapter = new MatchAdapter (getActivity(), ((MainActivity)getActivity()).getPastMatches(), futureMatches);
setListAdapter(adapter);
updateList();
}
public void updateList(){
this.getActivity().runOnUiThread(new Runnable() {
public void run() {
((BaseAdapter) getListAdapter()).notifyDataSetChanged();
getListView().refreshDrawableState();
getListView().invalidate();
}
});
}
public void onViewStateRestored(Bundle savedInstanceState)
{
super.onViewStateRestored(savedInstanceState);
}
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
refresh();
}
My adapter class:
public class MatchAdapter extends BaseAdapter
{
private final Activity context;
private LayoutInflater inflater;
private boolean time = false;
private boolean futureMatchAdapter = true;
private ArrayList<String> matchList;
public MatchAdapter(Context cont, ArrayList<String> matches, boolean isFutureMatchAdapter)
{
matchList = matches;
futureMatchAdapter = isFutureMatchAdapter;
context = (Activity) cont;
inflater = LayoutInflater.from(context);
}
public int getCount()
{
return MatchAdapter.size();
}
#Override
public Object getItem(int position)
{
return MatchAdapter.get(position);
}
public long getItemId(int position)
{
return position;
}
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
String curPos = "";
curPos = MatchAdapter.get(position);
//times, future matches and past matches are handled differently
if(curPos.contains("Last updated:"))
time = true;
else
time = false;
if (convertView == null)
{
holder = new ViewHolder();
if(time)
{
convertView = inflater.inflate(R.layout.time_item, null);
holder.title = (TextView) convertView.findViewById(R.id.item_time);
}
else
{
if(futureMatchAdapter)
{
convertView = inflater.inflate(R.layout.feed_item, null);
holder.title = (TextView) convertView.findViewById(R.id.item_title);
}
else
{
convertView = inflater.inflate(R.layout.past_feed_item, null);
holder.title = (TextView) convertView.findViewById(R.id.item_title_past);
}
}
convertView.setTag(holder);
}
else
holder = (ViewHolder) convertView.getTag();
if(futureMatchAdapter)
holder.title.setText(matchList.get(position));
else
{
String matchString = matchList.get(position);
String alwaysVisible = matchString.replace("<", "vs");
alwaysVisible = alwaysVisible.replace(">", "vs");
if(!time)
alwaysVisible = alwaysVisible.substring(0, alwaysVisible.length() - 1);
holder.title.setText(alwaysVisible);
if(matchString.contains(">"))
{
String winner = matchString.substring(0, matchString.indexOf(">")) + "won!";
alwaysVisible = alwaysVisible.concat(winner);
}
else if(matchString.contains("<"))
{
String winner = matchString.substring(matchString.indexOf("<") + 2, matchString.indexOf("\n")) + " won!";
alwaysVisible = alwaysVisible.concat(winner);
}
holder.title.setOnClickListener(new pastMatchesOnclickListener(alwaysVisible)
{
public void onClick(View v)
{
((TextView) v).setText(matchWinner);
}
});
}
return convertView;
}
static class ViewHolder
{
TextView title;
TextView time;
}
}
did you try to update your list using the adapter?
dataadapter.clear();
dataadapter.addAll(allDataResult);
To show and update content in a ListView you should:
Create or find your ListView
Create your ListAdapter
Add your ListAdapter to your ListView
Add data to your ListAdapter
Call notifyDataSetChanged() on your ListAdapter.
Example:
ListView listView = (ListView) findViewById(R.id.listview);
MyListAdapter myListAdapter = new MyListAdapter();
listView.setAdapter(myListAdapter);
myListAdapter.add("Hello");
myListAdapter.add("Hi");
myListAdapter.notifyDataSetChanged();
Note: if you're using a subclass of ArrayAdapter the notifyDataSetChanged() will be called for you when you use the methods add(), addAll(), etc.

Android: Do some action AFTER filling ListView elements

I have an activity with listview and attached footer. I created my custom adapter for filling ListView. After I filled it I need to do some actions.
This is my activity's code part:
public class MainActivity extends ListActivity {
final public String NO_USERS_IN_DB = "No users yet, please add some...";
DBAdapter db = new DBAdapter(this);
Activity activity = MainActivity.this;
private static final Pattern PATTERN = Pattern.compile(": *([^|]+)");
private static final int REQUEST_LOAD = 0;
boolean rewrite;
boolean userSelected = false;
final public int REQUEST_SAVE = 1;
boolean showAvatars;
boolean settingsGot = false;
int backgroundColor;
int titleColor;
int buttonBackgroundColor;
int buttonTextColor;
public class MyCustomAdapter extends ArrayAdapter<String> {
public MyCustomAdapter(Context context, int textViewResourceId,
String[] objects) {
super(context, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//return super.getView(position, convertView, parent);
if(!settingsGot){
getSettings();
settingsGot = true;
}
String[] users = getUsers();
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.main, parent, false);
TextView label=(TextView)row.findViewById(R.id.label);
label.setText(users[position]);
if(showAvatars){
ImageView icon=(ImageView)row.findViewById(R.id.icon);
byte[] bb = getAvatar(users[position]);
if(bb != null && bb.length != 0){
icon.setImageBitmap(BitmapFactory.decodeByteArray(bb, 0, bb.length));
icon.setVisibility(View.VISIBLE);
}
}
return row;
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
db.open();
String[] users = db.getUsersList();
boolean showList = true;
if (users[0].equals("NOUSERSINTHEBASE")){
users[0] = NO_USERS_IN_DB;
}
if (showList){
View footer = getLayoutInflater().inflate(R.layout.footer, null);
ListView listView = getListView();
listView.addFooterView(footer);
this.setListAdapter(new MyCustomAdapter(this,
R.layout.main, users));
}else{
setContentView(R.layout.footer);
}
db.close();
}
So, method I need to do some actions after method getView done its work. Where should I place my doSomeMoreActionsAfterGetView() ?
After setListAdapter you can change it...

Android listview showing only last element

i created custom listview with text and two buttons, i set up arraylist and adapter but my listview is showing every element as last, for ex. if i add 3 elements: "text1","text2","text3" my listview shows "text3", "text3" "text3" and i dont have any idea why.
private ListView lista;
private List<Piosenka> listaPiosenek;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (EditText) findViewById(R.id.editText1);
lista = (ListView) findViewById(R.id.listView1);
lista.setClickable(true);
}
public void update_listy() throws MalformedURLException, IOException
{
final List<Piosenka> listaPiosenek = new ArrayList<Piosenka>();
listaPiosenek.add(new Piosenka("text1"));
listaPiosenek.add(new Piosenka("text2"));
listaPiosenek.add(new Piosenka("text3"));
PiosenkaAdapter adapter = new PiosenkaAdapter(this, listaPiosenek);
lista.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long index)
{
System.out.println("sadsfsf");
}
});
lista.setAdapter(adapter);
}
Edit: PiosenkaAdapter code
public class PiosenkaAdapter extends BaseAdapter implements OnClickListener {
private Context context;
private List<Piosenka> listapiosenek;
public PiosenkaAdapter(Context context, List<Piosenka> listapiosenek) {
this.context = context;
this.listapiosenek = listapiosenek;
}
public int getCount() {
return listapiosenek.size();
}
public Object getItem(int position) {
return listapiosenek.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup viewGroup) {
Piosenka element = listapiosenek.get(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.listview_element, null);
}
TextView tvTytul = (TextView) convertView.findViewById(R.id.tvTytul);
tvTytul.setText(Piosenka.getTytul());
Button btnPobierz = (Button) convertView.findViewById(R.id.btnPobierz);
btnPobierz.setFocusableInTouchMode(false);
btnPobierz.setFocusable(false);
btnPobierz.setTag(element);
Button btnPlay = (Button) convertView.findViewById(R.id.btnPlay);
btnPlay.setFocusableInTouchMode(false);
btnPlay.setFocusable(false);
btnPlay.setOnClickListener(this);
btnPlay.setTag(element);
// btnRemove.setId(position);
return convertView;
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.btnPobierz:
Piosenka entry = (Piosenka) view.getTag();
listapiosenek.remove(entry);
notifyDataSetChanged();
break;
case R.id.btnPlay:
entry = (Piosenka) view.getTag();
listapiosenek.remove(entry);
notifyDataSetChanged();
break;
}
}
}
Try this...
lista.setAdapter(adapter);
adapter.notifyDataSetChanged();
Can you paste you PiosenkaAdapter's code?
I don't know your language, but the Piosenka variable is fetched correctly in getView()
Piosenka element = listapiosenek.get(position);
But this looks strange to me
TextView tvTytul = (TextView) convertView.findViewById(R.id.tvTytul);
tvTytul.setText(Piosenka.getTytul());
Piosenka.getTytul() looks to me as a static method call, where you should do a regular method call to element.getTytul() instead.

Categories

Resources