No items on ListControl - android

I have a problem while displaying a list on Sony SmartWatch 2.
I copied layouts from sample project (AdvancedControlSample) and I have the following class:
public class OpenPositionsView extends ControlExtension implements BaseView {
private static final String LOG_TAG = "TAGG";
private Context context;
private ControlViewGroup mLayout;
public OpenPositionsView(Context context, String hostAppPackageName) {
super(context, hostAppPackageName);
this.context = context;
mLayout = setup();
}
public ControlViewGroup setup() {
Log.i(LOG_TAG, "setup");
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.watch_positions, null);
ControlViewGroup mLayout = (ControlViewGroup) parseLayout(layout);
return mLayout;
}
public void show(Controller parent) {
int listCount = DataProvider.getInstance().getPositions().size();
parent.sendListCountM(R.id.watch_positions_listview, listCount);
parent.sendListPositionM(R.id.watch_positions_listview, 0);
parent.refreshLayout(R.layout.watch_positions, null);
Log.i(LOG_TAG, "show [listCount: " + listCount + "]");
}
#Override
public void onRequestListItem(final int layoutReference, final int listItemPosition) {
Log.d(LOG_TAG, "onRequestListItem [layoutReference: " + layoutReference + ", position: " + listItemPosition + "]");
if (layoutReference != -1 && listItemPosition != -1 && layoutReference == R.id.watch_positions_listview) {
ControlListItem item = createControlListItem(listItemPosition);
if (item != null) {
Log.d(LOG_TAG, "Sending list item");
sendListItem(item);
}
}
}
#Override
public void onListItemSelected(ControlListItem listItem) {
super.onListItemSelected(listItem);
}
#Override
public void onListItemClick(final ControlListItem listItem, final int clickType, final int itemLayoutReference) {
Log.d(LOG_TAG, "onListItemClick [listItemPosition: " + listItem.listItemPosition + ", clickType: " + clickType + ", itemLayoutReference: "
+ itemLayoutReference + "]");
}
public void onClick(int id) {
mLayout.onClick(id);
}
protected ControlListItem createControlListItem(int position) {
Log.d(LOG_TAG, "createControlListItem [position: " + position + "]");
ControlListItem item = new ControlListItem();
item.layoutReference = R.id.watch_positions_listview;
item.dataXmlLayout = R.layout.watch_positions_item;
item.listItemPosition = position;
// We use position as listItemId. Here we could use some other unique id
// to reference the list data
item.listItemId = position;
Position target = DataProvider.getInstance().getPosition(position);
if (target != null) {
Bundle symbolBundle = new Bundle();
symbolBundle.putInt(Control.Intents.EXTRA_LAYOUT_REFERENCE, R.id.watch_position_symbol);
symbolBundle.putString(Control.Intents.EXTRA_TEXT, target.getSymbol());
Bundle typeBundle = new Bundle();
typeBundle.putInt(Control.Intents.EXTRA_LAYOUT_REFERENCE, R.id.watch_position_type);
typeBundle.putString(Control.Intents.EXTRA_TEXT, target.getTypeAsString());
item.layoutData = new Bundle[2];
item.layoutData[0] = symbolBundle;
item.layoutData[1] = typeBundle;
Log.d(LOG_TAG, "Item list created: [symbolBundle: " + symbolBundle + ", typeBundle: " + typeBundle + "]");
}
return item;
}
protected Bundle[] createBundle(int position) {
Bundle[] result = new Bundle[2];
Position target = DataProvider.getInstance().getPosition(position);
if (target != null) {
Bundle symbolBundle = new Bundle();
symbolBundle.putInt(Control.Intents.EXTRA_LAYOUT_REFERENCE, R.id.watch_position_symbol);
symbolBundle.putString(Control.Intents.EXTRA_TEXT, target.getSymbol());
Bundle typeBundle = new Bundle();
typeBundle.putInt(Control.Intents.EXTRA_LAYOUT_REFERENCE, R.id.watch_position_type);
typeBundle.putString(Control.Intents.EXTRA_TEXT, target.getTypeAsString());
result[0] = symbolBundle;
result[1] = typeBundle;
}
return result;
}
}
However, onRequestListItem gets called and createControlListItem returns a correct item list. Touching the display gives me the following result:
onListItemClick [listItem: com.sonyericsson.extras.liveware.extension.util.control.ControlListItem#423b6960, clickType: 0, itemLayoutReference: -1]
The problem is, I do not see any of "added" list items :(

Make sure you also copied the List-related intents from the Manifest.xml:
<action android:name="com.sonyericsson.extras.aef.control.LIST_REFERESH_REQUEST" />
<action android:name="com.sonyericsson.extras.aef.control.LIST_REQUEST_ITEM" />
<action android:name="com.sonyericsson.extras.aef.control.LIST_ITEM_CLICK" />
<action android:name="com.sonyericsson.extras.aef.control.LIST_ITEM_SELECTED" />

Couple questions for you:
What is being shown on the screen? Is it just blank?
Are you calling showLayout() and sendListCount()? I don't see them in the above code. In the sample code in onResume() you should see something like:
showLayout(R.layout.layout_test_list, null);
sendListCount(R.id.listView, mListContent.length);
These need to be called.
Did you make sure that sendListItem(item) is actually being called?

Aren't you adding black text items to layout with black background? :) Please check your layouts.

Related

Android ListView not refreshing after notifyDataSetChanged is called

I have struggled to load more items on listview after calling notifyDataSetChanged() method
Here is the code block for setting user scroll action on listview
lv = (ListView) getActivity().findViewById(R.id.list);
adapter = new ItemListAdapter(getActivity(), getList(), 2);
progressDialog.show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
lv.setAdapter(adapter);
progressDialog.dismiss();
adapter.notifyDataSetChanged();
}
}, SPLASH_TIME_OUT);
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
userScrolled = true;
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (userScrolled) {
userScrolled = false;
progressDialog.getWindow().setGravity(Gravity.BOTTOM);
progressDialog.show();
updateListView();
}
}
});
And here is my updateListView method:
private void updateListView() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (appPreference.getLoadStatus().equals("0")) {
for (int i = 0; i < getListMore().size(); i++) {
Log.i("MORE VALUES", "" + getListMore().get(i));
getList().add(getListMore().get(i));
}
appPreference.saveLoadStatus("1");
}
progressDialog.dismiss();
adapter.notifyDataSetChanged();
}
}, 100);
}
Here is my getList() method
public List<ItemList> getList() {
ContentResolver cr = getActivity().getContentResolver();
String where = Products.SYNCSTATUS + " != 3";
Cursor c = cr.query(Products.BASEURI, null, where, null, Products.ID + " DESC");
list = new ArrayList<ItemList>();
try {
if (c.getCount() > 0) {
c.moveToFirst();
do {
int colN = c.getColumnIndex(Products.PRODUCT);
int colP = c.getColumnIndex(Products.ON_HAND);
int colI = c.getColumnIndex(Products.ID);
int colD = c.getColumnIndex(Products.SKU);
int colPr = c.getColumnIndex(Products.PRICE);
int colUp = c.getColumnIndex(Products.UPDATE);
String n = c.getString(colNad);
String p = c.getString(colPle);
long i = c.getLong(colIMEI);
String d = c.getString(colDec);
String pr = c.getString(colProd);
String upd = c.getString(colUpdated);
if (!Validating.areSet(upd))
upd = getString(R.string.strnever);
if (tabletsize) {
list.add(new ItemList(n.toUpperCase(Locale.getDefault()), pr, p, i,
d, upd));
} else {
list.add(new ItemList(getString(R.string.strproduct).toUpperCase(Locale.getDefault()) + ": " +
n.toUpperCase(Locale.getDefault()),
getString(R.string.strprice).toUpperCase(Locale.getDefault()) + ": " +
pr.toUpperCase(Locale.getDefault()),
getString(R.string.strtotalqty).toUpperCase(Locale.getDefault()) + ": " + p, i,
getString(R.string.strsku).toUpperCase(Locale.getDefault()) + ": " + d,
getString(R.string.strlastsell).toUpperCase(Locale.getDefault()) + ": " + upd));
}
} while (c.moveToNext());
} else {
String n = getString(R.string.strnodata).toUpperCase(Locale.getDefault());
String p = " ";
long i = 0;
String d = null;
list.add(new ItemList(n, "", p, i, d));
}
} finally {
if (c != null) {
c.close();
}
}
return list;
}
My intention is to load more items using getListMore() method which load data from database, add them into getList() method which returns List<ItemList>
The problem comes when i scroll the listview there is no new data loaded onto it ,the logs shows the
Log.i("MORE VALUES", "" + getListMore().get(i)); returned the data from database but no data has been shown on listview.
Can anyone help with the issue as why the data is not loaded and how to fix it?
Thanks
Can you try changing:
new Handler().postDelayed(new Runnable() {
to:
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
The method adapter.notifyDataSetChanged(); needs to be called from the main thread only.
You are actually fetching the data, adding it into list with getList() but not setting that list. you probably need to setlist() with new values.
Something like, setList(new updated list here) and then adapter.notifyDataSetChanged()
you need to make getList() more clear, see every time you get getList() and add new item in it, it reinstanitate the list, add the old items in it which you have added veru first time. better to make a change the method something like this.
public List<ItemList> getList() {
if(list != null || list.size() > 0) {
return list;
}
ContentResolver cr = getActivity().getContentResolver();
String where = Products.SYNCSTATUS + " != 3";
Cursor c = cr.query(Products.BASEURI, null, where, null, Products.ID + " DESC");
list = new ArrayList<ItemList>();
try {
if (c.getCount() > 0) {
c.moveToFirst();
do {
int colN = c.getColumnIndex(Products.PRODUCT);
int colP = c.getColumnIndex(Products.ON_HAND);
int colI = c.getColumnIndex(Products.ID);
int colD = c.getColumnIndex(Products.SKU);
int colPr = c.getColumnIndex(Products.PRICE);
int colUp = c.getColumnIndex(Products.UPDATE);
String n = c.getString(colNad);
String p = c.getString(colPle);
long i = c.getLong(colIMEI);
String d = c.getString(colDec);
String pr = c.getString(colProd);
String upd = c.getString(colUpdated);
if (!Validating.areSet(upd))
upd = getString(R.string.strnever);
if (tabletsize) {
list.add(new ItemList(n.toUpperCase(Locale.getDefault()), pr, p, i,
d, upd));
} else {
list.add(new ItemList(getString(R.string.strproduct).toUpperCase(Locale.getDefault()) + ": " +
n.toUpperCase(Locale.getDefault()),
getString(R.string.strprice).toUpperCase(Locale.getDefault()) + ": " +
pr.toUpperCase(Locale.getDefault()),
getString(R.string.strtotalqty).toUpperCase(Locale.getDefault()) + ": " + p, i,
getString(R.string.strsku).toUpperCase(Locale.getDefault()) + ": " + d,
getString(R.string.strlastsell).toUpperCase(Locale.getDefault()) + ": " + upd));
}
} while (c.moveToNext());
} else {
String n = getString(R.string.strnodata).toUpperCase(Locale.getDefault());
String p = " ";
long i = 0;
String d = null;
list.add(new ItemList(n, "", p, i, d));
}
} finally {
if (c != null) {
c.close();
}
}
return list;
}

Dynamic ListView scroll TextView changed automatically

when i click + button increment the price and click - button decrease the price it's work perfectly but when i scroll listview the value of tvPrices (TextView) is changed.
What should i do for the stay increment price?
here is my adapter
public class ListAdapter extends BaseAdapter {
public ArrayList<Integer> quantity = new ArrayList<Integer>();
public ArrayList<Integer> price = new ArrayList<Integer>();
private String[] listViewItems, prices, static_price;
TypedArray images;
View row = null;
static String get_price, get_quntity;
int g_quntity, g_price, g_minus;
private Context context;
CustomButtonListener customButtonListener;
static HashMap<String, String> map = new HashMap<>();
public ListAdapter(Context context, String[] listViewItems, TypedArray images, String[] prices) {
this.context = context;
this.listViewItems = listViewItems;
this.images = images;
this.prices = prices;
for (int i = 0; i < listViewItems.length; i++) {
quantity.add(0);
price.add(0);
}
}
public void setCustomButtonListener(CustomButtonListener customButtonListner) {
this.customButtonListener = customButtonListner;
}
#Override
public int getCount() {
return listViewItems.length;
}
#Override
public String getItem(int position) {
return listViewItems[position];
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ListViewHolder listViewHolder;
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.activity_custom_listview, parent, false);
listViewHolder = new ListViewHolder();
listViewHolder.tvProductName = (TextView) row.findViewById(R.id.tvProductName);
listViewHolder.ivProduct = (ImageView) row.findViewById(R.id.ivproduct);
listViewHolder.tvPrices = (TextView) row.findViewById(R.id.tvProductPrice);
listViewHolder.btnPlus = (ImageButton) row.findViewById(R.id.ib_addnew);
listViewHolder.edTextQuantity = (EditText) row.findViewById(R.id.editTextQuantity);
listViewHolder.btnMinus = (ImageButton) row.findViewById(R.id.ib_remove);
static_price = context.getResources().getStringArray(R.array.Price);
row.setTag(listViewHolder);
} else {
row = convertView;
listViewHolder = (ListViewHolder) convertView.getTag();
}
listViewHolder.ivProduct.setImageResource(images.getResourceId(position, -1));
try {
listViewHolder.edTextQuantity.setText(quantity.get(position) + "");
} catch (Exception e) {
e.printStackTrace();
}
listViewHolder.btnPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (customButtonListener != null) {
customButtonListener.onButtonClickListener(position, listViewHolder.edTextQuantity, 1);
quantity.set(position, quantity.get(position) + 1);
price.set(position, price.get(position) + 1);
row.getTag(position);
get_price = listViewHolder.tvPrices.getText().toString();
g_price = Integer.valueOf(static_price[position]);
get_quntity = listViewHolder.edTextQuantity.getText().toString();
g_quntity = Integer.valueOf(get_quntity);
map.put("" + listViewHolder.tvProductName.getText().toString(), " " + listViewHolder.edTextQuantity.getText().toString());
listViewHolder.tvPrices.setText("" + g_price * g_quntity);
// Log.d("A ", "" + a);
// Toast.makeText(context, "A" + a, Toast.LENGTH_LONG).show();
// Log.d("Position ", "" + position);
// System.out.println(+position + " Values " + map.values());
ShowHashMapValue();
listViewHolder.tvPrices.setText("" + g_price * g_quntity);
}
}
});
listViewHolder.btnMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (customButtonListener != null) {
customButtonListener.onButtonClickListener(position, listViewHolder.edTextQuantity, -1);
if (quantity.get(position) > 0)
quantity.set(position, quantity.get(position) - 1);
get_price = listViewHolder.tvPrices.getText().toString();
g_minus = Integer.valueOf(get_price);
g_price = Integer.valueOf(static_price[position]);
int minus = g_minus - g_price;
if (minus >= g_price) {
listViewHolder.tvPrices.setText("" + minus);
}
map.put("" + listViewHolder.tvProductName.getText().toString(), " " + listViewHolder.edTextQuantity.getText().toString());
ShowHashMapValue();
}
}
});
listViewHolder.tvProductName.setText(listViewItems[position]);
listViewHolder.tvPrices.setText(prices[position]);
return row;
}
private void ShowHashMapValue() {
/**
* get the Set Of keys from HashMap
*/
Set setOfKeys = map.keySet();
/**
* get the Iterator instance from Set
*/
Iterator iterator = setOfKeys.iterator();
/**
* Loop the iterator until we reach the last element of the HashMap
*/
while (iterator.hasNext()) {
/**
* next() method returns the next key from Iterator instance.
* return type of next() method is Object so we need to do DownCasting to String
*/
String key = (String) iterator.next();
/**
* once we know the 'key', we can get the value from the HashMap
* by calling get() method
*/
String value = map.get(key);
System.out.println("Key: " + key + ", Value: " + value);
}
}
}
In onclick, after you decrement the value call notifyDataSetChanged()
notifyDataSetChanged
but its a costly operation, since it refreshes complete list

Android ListView on Ready or on Initialized listener

I am having a listview which I am populating from a database.
The listview is taking some time(<300ms) to populate the list.
If I am doing a smoothScrollToPosition on the onActivityCreated function it is doing nothing.
On the OnCreate function I had to wait for ~200ms before I could call smoothScrollToPosition before which even the ListView Object is not initialized.
I can use the getViewTreeObserver as below which runs fine but it requires the minimum sdk version 16. I was trying to get it working for version 14~15.
mListView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
mListView.smoothScrollToPosition(adapter.getCount());
// unregister listener (this is important)
mListView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
The code I am having -
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
list = new ArrayList<Chat>();
db = new DBAdapter(getContext());
adapter = new CustomChatAdapter(getContext(), list);
Log.d("ListView1", "Value of f: " + f);
thread= new Thread(){
#Override
public void run(){
try {
synchronized(this){
wait(200);
}
}
catch(InterruptedException ex){
Log.d("ListView1", "Interrupted Exception: " +ex.toString());
}
Log.d("ListView1", "Adapter Count: " +adapter.getCount());
mListView.smoothScrollToPosition(adapter.getCount());
}
};
getMsg("1", getActivity().getIntent().getStringExtra("key"));
thread.start();
Log.d("ListView1", "Adapter Count: " +adapter.getCount());
//mListView.smoothScrollToPosition(adapter.getCount());
}
public void getMsg(String myid, String friend_id) {
list.clear();
try {
Cursor cur = db.get_friend_shouts(myid,friend_id);
String img_id1 = "";
String img_id2 ="";
if (cur != null) {
if (cur.moveToFirst()) {
do {
img_id1 = cur.getString(cur.getColumnIndex("image_id"));
img_id1 = img_id1 == null ? "null" : img_id1;
img_id2 = cur.getString(cur.getColumnIndex("r_img_id"));
img_id2 = img_id2 == null ? "null" : img_id2;
list.add(new Chat( img_id1 , cur.getString(cur.getColumnIndex("firstname")) + " " + cur.getString(cur.getColumnIndex("lastname")), cur.getString(cur.getColumnIndex("user_id")),
cur.getString(cur.getColumnIndex("shout_msg")) ,
img_id2, cur.getString(cur.getColumnIndex("r_firstname")) + " " + cur.getString(cur.getColumnIndex("r_lastname")) , cur.getString(cur.getColumnIndex("r_user_id")) , cur.getString(cur.getColumnIndex("rec_time")) ));
//Log.d("ListView1", "User details: " + cur.getString(cur.getColumnIndex("user_id")) + " " + cur.getString(cur.getColumnIndex("firstname")) + cur.getString(cur.getColumnIndex("lastname")) + " " + cur.getString(cur.getColumnIndex("image_id")));
} while (cur.moveToNext());
}
}
adapter.notifyDataSetChanged();
if(mListView!=null)
mListView.smoothScrollToPosition(adapter.getCount());
} catch (Exception e) {
Log.d("ListView1", "getMsg Error: " + e.toString());
}
}
The ArrayAdapter class -
public class CustomChatAdapter extends ArrayAdapter<Chat> {
private final Context context;
private final List<Chat> list;
public CustomChatAdapter(Context context, ArrayList<Chat> presidents) {
super(context, R.layout.chatrowlayout, presidents);
this.context = context;
this.list = presidents;
}
static class ViewContainer { public ImageView imageView; public TextView txtMsg; public ImageView imageView1; public TextView txtTime; }
#Override
public View getView(int position, View view, ViewGroup parent) {
ViewContainer viewContainer;
View rowView = view;
//---print the index of the row to examine---
//Log.d("ListView1",String.valueOf(position));
//if(rowView == null) {
viewContainer = new ViewContainer();
LayoutInflater inflater = LayoutInflater.from(context);
rowView= inflater.inflate(R.layout.chatrowlayout, null, true);
viewContainer.txtMsg = (TextView) rowView.findViewById(R.id.msgText);
viewContainer.imageView = (ImageView) rowView.findViewById(R.id.icon1);
viewContainer.imageView1 = (ImageView) rowView.findViewById(R.id.icon2);
viewContainer.txtTime = (TextView) rowView.findViewById(R.id.timeText);
rowView.setTag(viewContainer);
/*} else {
viewContainer = (ViewContainer) rowView.getTag();
}*/
viewContainer.txtMsg.setText(list.get(position).getMsg());
viewContainer.txtTime.setText(list.get(position).getMsg_time());
if(list.get(position).getS_id().equals("1")) {
viewContainer.imageView.setImageBitmap(BitmapFactory.decodeFile(new Info().p + File.separator+ "image_" + list.get(position).getPic_id1() + ".jpeg" ));
viewContainer.imageView1.setAlpha(0);
viewContainer.txtMsg.setGravity(Gravity.LEFT);
} else {
viewContainer.imageView1.setImageBitmap(BitmapFactory.decodeFile(new Info().p + File.separator+ "image_" + list.get(position).getPic_id1() + ".jpeg" ));
viewContainer.imageView.setAlpha(0);
viewContainer.txtMsg.setGravity(Gravity.RIGHT);
}
return rowView;
}
}
removeGlobalOnLayoutListerner for pre SDK 16, addOnGlobalLayout works for pre 16.
OnCreate is too early.
You should wait for the layout to be inflated. Smooth scrolling in onResume should do the trick:
#Override
protected void onResume() {
mListView.smoothScrollToPosition(adapter.getCount());
}

Sectioning date header in a ListView that has adapter extended by CursorAdapter

I am trying to build a demo chatting App.I want to show the messages with section headers as Dates like "Today","Yesterday","May 21 2015" etc.I have managed to achieve this but since the new View method gets called whenever I scroll the list.The headers and messages get mixed up.
For simplicity, I have kept the header in the layouts itself and changing its visibility(gone and visible) if the date changes.
Can you help me out with this? Let me know if anyone needs any more info to be posted in the question.
public class ChatssAdapter extends CursorAdapter {
private Context mContext;
private LayoutInflater mInflater;
private Cursor mCursor;
private String mMyName, mMyColor, mMyImage, mMyPhone;
// private List<Contact> mContactsList;
private FragmentActivity mActivity;
private boolean mIsGroupChat;
public ChatssAdapter(Context context, Cursor c, boolean groupChat) {
super(context, c, false);
mContext = context;
mMyColor = Constants.getMyColor(context);
mMyName = Constants.getMyName(context);
mMyImage = Constants.getMyImageUrl(context);
mMyPhone = Constants.getMyPhone(context);
mIsGroupChat = groupChat;
mCursor = c;
// mActivity = fragmentActivity;
/*try {
mContactsList = PinchDb.getHelper(mContext).getContactDao().queryForAll();
} catch (SQLException e) {
e.printStackTrace();
}*/
}
#Override
public int getItemViewType(int position) {
Cursor cursor = (Cursor) getItem(position);
return getItemViewType(cursor);
}
private int getItemViewType(Cursor cursor) {
boolean type;
if (mIsGroupChat)
type = cursor.getString(cursor.getColumnIndex(Chat.COLMN_CHAT_USER)).compareTo(mMyPhone) == 0;
else type = cursor.getInt(cursor.getColumnIndex(Chat.COLMN_FROM_ME)) > 0;
if (type) {
return 0;
} else {
return 1;
}
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = null;
int itemViewType = getItemViewType(cursor);
if (v == null) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (itemViewType == 0) {
v = mInflater.inflate(R.layout.row_chat_outgoing, parent, false);
} else {
v = mInflater.inflate(R.layout.row_chat_incoming, parent, false);
}
}
return v;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = new ViewHolder();
View v = view;
final Chat chat = new Chat(cursor);
boolean fromMe = mIsGroupChat ? chat.getUser().compareTo(mMyPhone) == 0 : chat.isFrom_me();
if (fromMe) {
// LOGGED IN USER'S DATA SETTING....
holder.chat_name = (StyleableTextView) v
.findViewById(R.id.chat_user_name);
holder.chat_time = (StyleableTextView) v
.findViewById(R.id.chat_time);
holder.chat_tag = (StyleableTextView) v
.findViewById(R.id.chat_tag);
int color = Color.parseColor("#FFFFFF");
v.setBackgroundColor(color);
holder.chat_name.setText("#You");
holder.chat_time.setText(AppUtil.getEventTime(chat.getTimestampLong()));
// header text setting and process..
holder.chat_header_text = (TextView) v.findViewById(R.id.header_text);
String str_date = AppUtil.covertToDate(chat.getTimestampLong());
String pref_date = SharePreferencesUtil.getSharedPreferencesString(mContext, Constants.CHAT_TIMESTAMP, "");
if (!str_date.equalsIgnoreCase(pref_date)) {
holder.chat_header_text.setVisibility(View.VISIBLE);
SharePreferencesUtil.putSharedPreferencesString(mContext, Constants.CHAT_TIMESTAMP, str_date);
holder.chat_header_text.setText(str_date);
} else {
holder.chat_header_text.setVisibility(View.GONE);
}
String firstWord, theRest;
String mystring = chat.getText();
String arr[] = mystring.split(" ", 2);
if (arr.length > 1) {
firstWord = arr[0]; // the word with hash..
theRest = arr[1]; // rest of the body..
holder.chat_tag.setText(Html.fromHtml("<font color=\"#999999\"><b>" + firstWord + "</b></font>" + " " + "<font color=\"#000000\">" + theRest + "</font>"));
// holder.chat_text.setText(theRest);
// holder.chat_text.setClickable(false);
} else {
String msg = arr[0]; // the word with hash..
holder.chat_tag.setText(Html.fromHtml("<font color=\"#999999\"><b>" + msg + "</b></font>"));
//holder.chat_text.setText("");
}
updateTimeTextColorAsPerStatus(holder.chat_time, chat.getStatus());
v.setTag(holder);
} else {
// OTHER USER'S DATA SETTING....
holder.chat_name = (StyleableTextView) v
.findViewById(R.id.chat_user_name);
holder.chat_time = (StyleableTextView) v
.findViewById(R.id.chat_time);
holder.chat_tag = (StyleableTextView) v
.findViewById(R.id.chat_tag);
holder.chat_image = (ImageView) v
.findViewById(R.id.chat_profile_image);
String image = cursor.getString(cursor.getColumnIndex("image"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String color = cursor.getString(cursor.getColumnIndex("color"));
// set the values...
if (holder.chat_image != null) {
MImageLoader.displayImage(context, image, holder.chat_image, R.drawable.round_user_place_holder);
}
int back_color = Color.parseColor("#FFFFFF");
v.setBackgroundColor(back_color);
holder.chat_name.setText(name);
holder.chat_time.setText(AppUtil.getEventTime(chat.getTimestampLong()));
// header text setting and process..
holder.chat_header_text = (TextView) v.findViewById(R.id.header_text);
String str_date = AppUtil.covertToDate(chat.getTimestampLong());
String pref_date = SharePreferencesUtil.getSharedPreferencesString(mContext, Constants.CHAT_TIMESTAMP, "");
Log.d("eywa", "str date is ::::: " + str_date + " pref date is :::::: " + pref_date);
/*if (!TextUtils.isEmpty(pref_date)) {
if (!pref_date.contains(str_date)) {
holder.chat_header_text.setVisibility(View.VISIBLE);
SharePreferencesUtil.putSharedPreferencesString(mContext, Constants.CHAT_TIMESTAMP, pref_date + str_date);
holder.chat_header_text.setText(str_date);
} else {
holder.chat_header_text.setVisibility(View.GONE);
}
} else {
holder.chat_header_text.setVisibility(View.VISIBLE);
SharePreferencesUtil.putSharedPreferencesString(mContext, Constants.CHAT_TIMESTAMP, pref_date + str_date);
holder.chat_header_text.setText(str_date);
}*/
if (!str_date.equalsIgnoreCase(pref_date)) {
holder.chat_header_text.setVisibility(View.VISIBLE);
SharePreferencesUtil.putSharedPreferencesString(mContext, Constants.CHAT_TIMESTAMP, str_date);
holder.chat_header_text.setText(str_date);
} else {
holder.chat_header_text.setVisibility(View.GONE);
}
String firstWord, theRest;
String mystring = chat.getText();
String arr[] = mystring.split(" ", 2);
if (arr.length > 1) {
firstWord = arr[0]; // the word with hash..
theRest = arr[1]; // rest of the body..
holder.chat_tag.setText(Html.fromHtml("<font color=\"#999999\"><b>" + firstWord + "</b></font>" + " " + "<font color=\"#000000\">" + theRest + "</font>"));
// holder.chat_text.setClickable(false);
} else {
String msg = arr[0]; // the word with hash..
holder.chat_tag.setText(Html.fromHtml("<font color=\"#999999\"><b>" + msg + "</b></font>"));
// holder.chat_text.setText("");
}
String phone = cursor.getString(cursor.getColumnIndex("user"));
final Contact contact = new Contact(name, phone, "", color, image);
if (holder.chat_image != null) {
holder.chat_image.setTag(contact);
// holder.chat_name.setTag(contact);
holder.chat_image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Contact con = (Contact) v.getTag();
Intent intent = new Intent(mContext, OtherProfileActivity.class);
intent.putExtra(Constants.EXTRA_CONTACT, con);
mContext.startActivity(intent);
}
});
}
v.setTag(holder);
}
/*else
{
view=
}*/
}
private void updateTimeTextColorAsPerStatus(TextView chat_time, int status) {
if (status == 0) chat_time.setVisibility(View.INVISIBLE);
else {
chat_time.setVisibility(View.VISIBLE);
/* if (status == 1)
chat_time.setTextColor(mContext.getResources().getColor(android.R.color.white));*/
if (status == 2)
chat_time.setTextColor(mContext.getResources().getColor(android.R.color.darker_gray));
else if (status == 3)
chat_time.setTextColor(mContext.getResources().getColor(android.R.color.black));
}
}
#Override
public int getViewTypeCount() {
return 2;
}
public class ViewHolder {
public StyleableTextView chat_name;
public StyleableTextView chat_time;
public StyleableTextView chat_tag;
public ImageView chat_image;
public TextView chat_header_text;
}
#Override
public int getCount() {
if (getCursor() == null) {
return 0;
} else {
return getCursor().getCount();
}
}
}

After rotating screen, always first timer beginning a count

Half month i trying fix this problem, its my second solution and i get old error.
My goal is to write a listView with timer in every row with Start and Stop buttons, after rotating screen all timers should work correctly, but how in pre-solution after rotation screen, first position in listview get time last/lower position.
As for link with these two solution i see just logic of getView() method, and i'm on 100% sure that is the main problem.
Can anybody help me with this, i am at an impasse. Problematic piace of code:
if(isItStart.get(position)){
holder.stop.setEnabled(true);
holder.start.setEnabled(false);
handler.postDelayed(updateTimeThread,0);
}
Here is full class.
ListView listView;
MyAdapter adapter;
Handler handler;
SQLiteDatabase db;
List<Tracker> trackerList;
Tracker tracker;
List<Boolean> isItStart,historyIsItStart;
List<Long> startTime,historyStartTime;
List<Long> lastPauseList,historyLastPauseList;
List<Long> updateTimeList, historyUpdateTimeList;
List<Long> daysList,historyDayList;
List<Long> hoursList,historyHoursList;
List<Long> minutesList,historyMinutes;
List<Long> secondsList,historySecondsList;
int trackerCount;
static final String LOG_TAG = "myTag";
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
db = RemindMe.db;
trackerList = Tracker.getListAll(db);
trackerCount=trackerList.size();
initLists();
for (int i = 0; i < trackerCount; i++) {
startTime.add(0L);
lastPauseList.add(0L);
updateTimeList.add(0L);
daysList.add(0L);
hoursList.add(0L);
minutesList.add(0L);
secondsList.add(0L);
isItStart.add(false);
historyStartTime.add(startTime.get(i));
historyLastPauseList.add(lastPauseList.get(i));
historyUpdateTimeList.add(updateTimeList.get(i));
historyDayList.add(daysList.get(i));
historyHoursList.add(hoursList.get(i));
historyMinutes.add(minutesList.get(i));
historySecondsList.add(secondsList.get(i));
historyIsItStart.add(isItStart.get(i));
}
listView = (ListView)findViewById(R.id.listView);
String[] from = {Tracker.COL_NAME,Tracker.COL_ELAPSED_TIME,Tracker.COL_ELAPSED_TIME,Tracker.COL_ELAPSED_TIME,Tracker.COL_ELAPSED_TIME};
int[] to = {R.id.tvName,R.id.tvDays,R.id.tvHours,R.id.tvMinutes,R.id.tvSeconds};
adapter = new MyAdapter(this,R.layout.list_item,Tracker.getAll(db),from,to,0);
adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
#Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
long day,hour,min,sec;
long time = cursor.getLong(columnIndex);
switch(view.getId()){
case R.id.tvDays:
TextView days = (TextView)view;
days.setText("days");
return true;
case R.id.tvHours:
TextView hours = (TextView)view;
hours.setText("hours");
return true;
case R.id.tvMinutes:
TextView minutes = (TextView)view;
minutes.setText("min");
return true;
case R.id.tvSeconds:
TextView seconds = (TextView)view;
if(time!=0){
sec = time/1000;
seconds.setText(String.valueOf(sec));
}else{
seconds.setText("null");
}
return true;
}
return false;
}
});
listView.setAdapter(adapter);
getSupportLoaderManager().initLoader(1,null,this).forceLoad();
}
void initLists(){
startTime = new ArrayList<Long>(trackerCount);
lastPauseList = new ArrayList<Long>(trackerCount);
updateTimeList = new ArrayList<Long>(trackerCount);
daysList = new ArrayList<Long>(trackerCount);
hoursList = new ArrayList<Long>(trackerCount);
minutesList = new ArrayList<Long>(trackerCount);
secondsList = new ArrayList<Long>(trackerCount);
isItStart = new ArrayList<Boolean>(trackerCount);
historySecondsList = new ArrayList<Long>(trackerCount);
historyMinutes = new ArrayList<Long>(trackerCount);
historyHoursList = new ArrayList<Long>(trackerCount);
historyDayList = new ArrayList<Long>(trackerCount);
historyUpdateTimeList = new ArrayList<Long>(trackerCount);
historyLastPauseList = new ArrayList<Long>(trackerCount);
historyStartTime = new ArrayList<Long>(trackerCount);
historyIsItStart = new ArrayList<Boolean>(trackerCount);
}
#Override
public void onClick(View v) {
Intent intent = new Intent(this,AddTrack.class);
startActivity(intent);
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
return new TrackerLoader(this,db);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.swapCursor(cursor);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
static class TrackerLoader extends android.support.v4.content.CursorLoader{
SQLiteDatabase db;
TrackerLoader(Context context,SQLiteDatabase db){
super(context);
this.db=db;
}
#Override
public Cursor loadInBackground() {
return Tracker.getAll(db);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d(LOG_TAG, "onSavedInstanceState---------------------------------------------------------------!");
for (int i = 0; i <trackerCount ; i++) {
historyStartTime.set(i,startTime.get(i));
historyLastPauseList.set(i, lastPauseList.get(i));
historyUpdateTimeList.set(i,updateTimeList.get(i));
historyDayList.set(i, daysList.get(i));
historyHoursList.set(i,hoursList.get(i));
historyMinutes.set(i, minutesList.get(i));
historySecondsList.set(i,secondsList.get(i));
historyIsItStart.set(i, isItStart.get(i));
outState.putSerializable("startTime " + i, historyStartTime.get(i));
outState.putSerializable("lastPause " + i, historyLastPauseList.get(i));
outState.putSerializable("updateTime " + i, historyUpdateTimeList.get(i));
outState.putSerializable("dayList " + i, historyDayList.get(i));
outState.putSerializable("hoursList " + i, historyHoursList.get(i));
outState.putSerializable("minutesList " + i, historyMinutes.get(i));
outState.putSerializable("secondsList " + i, historySecondsList.get(i));
outState.putSerializable("isItStart " + i, historyIsItStart.get(i));
Log.d(LOG_TAG, "startTime " + getTime((Long) outState.getSerializable("startTime " + i)));
Log.d(LOG_TAG, "lastPause " + getTime((Long) outState.getSerializable("lastPause " + i)));
Log.d(LOG_TAG, "updateTime " + getTime((Long) outState.getSerializable("updateTime " + i)));
Log.d(LOG_TAG, "dayList " + getTime((Long) outState.getSerializable("dayList " + i)));
Log.d(LOG_TAG, "hoursList " + getTime((Long) outState.getSerializable("hoursList " + i)));
Log.d(LOG_TAG, "minutesList " + getTime((Long) outState.getSerializable("minutesList " + i)));
Log.d(LOG_TAG, "secondsList " + outState.getSerializable("secondsList " + i));
Log.d(LOG_TAG, "isItStart " + outState.getSerializable("isItStart " + i));
Log.d(LOG_TAG, "position " + i);
Log.d(LOG_TAG,"-----------------------------------!");
}
Log.d(LOG_TAG,"END onSavedInstanceState-------------------------------------------------------------!");
for (int i = 0; i < trackerCount; i++) {
Log.d(LOG_TAG,"secondsList "+i+ " "+secondsList.get(i));
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.d(LOG_TAG, "onRestoreInstanceState-------------------------------------------------------!");
for (int i = 0; i <trackerCount ; i++) {
historyStartTime.set(i,(Long)savedInstanceState.getSerializable("startTime "+i));
historyLastPauseList.set(i,(Long)savedInstanceState.getSerializable("lastPause "+i));
historyUpdateTimeList.set(i,(Long)savedInstanceState.getSerializable("updateTime "+i));
historyDayList.set(i,(Long)savedInstanceState.getSerializable("dayList "+i));
historyHoursList.set(i,(Long)savedInstanceState.getSerializable("hoursList "+i));
historyMinutes.set(i,(Long)savedInstanceState.getSerializable("minutesList "+i));
historySecondsList.set(i,(Long)savedInstanceState.getSerializable("secondsList "+i));
historyIsItStart.set(i,(Boolean)savedInstanceState.getSerializable("isItStart "+i));
startTime.set(i,historyStartTime.get(i));
lastPauseList.set(i,historyLastPauseList.get(i));
updateTimeList.set(i,historyUpdateTimeList.get(i));
daysList.set(i,historyDayList.get(i));
hoursList.set(i,historyHoursList.get(i));
minutesList.set(i,historyMinutes.get(i));
secondsList.set(i,historySecondsList.get(i));
isItStart.set(i, historyIsItStart.get(i));
Log.d(LOG_TAG, "startTime " + getTime((Long) savedInstanceState.getSerializable("startTime " + i)));
Log.d(LOG_TAG,"lastPause " + getTime((Long) savedInstanceState.getSerializable("lastPause " + i)));
Log.d(LOG_TAG,"updateTime " + getTime((Long) savedInstanceState.getSerializable("updateTime " + i)));
Log.d(LOG_TAG,"dayList " + getTime((Long) savedInstanceState.getSerializable("dayList " + i)));
Log.d(LOG_TAG,"hoursList " + getTime((Long) savedInstanceState.getSerializable("hoursList " + i)));
Log.d(LOG_TAG,"minutesList " + getTime((Long) savedInstanceState.getSerializable("minutesList " + i)));
Log.d(LOG_TAG, "secondsList " + savedInstanceState.getSerializable("secondsList " + i));
Log.d(LOG_TAG,"isItStart "+savedInstanceState.getSerializable("isItStart " + i));
Log.d(LOG_TAG,"position "+i);
Log.d(LOG_TAG,"----------------------------------------------------------------");
}
Log.d(LOG_TAG,"END onRestoreIntstanceState-------------------------------------------------------------!");
}
private class MyAdapter extends SimpleCursorAdapter{
Context context;
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
MyAdapter(Context context,int resourceID,Cursor cursor,String[] from,int[]to,int flags){
super(context, resourceID, cursor, from, to, flags);
this.context = context;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
View row = convertView;
final ViewHolder holder;
tracker = trackerList.get(position);
if(row==null){
holder = new ViewHolder();
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(R.layout.list_item,parent,false);
holder.name= (TextView)row.findViewById(R.id.tvName);
holder.days = (TextView)row.findViewById(R.id.tvDays);
holder.hours = (TextView)row.findViewById(R.id.tvHours);
holder.minutes = (TextView)row.findViewById(R.id.tvMinutes);
holder.seconds = (TextView)row.findViewById(R.id.tvSeconds);
holder.start = (Button)row.findViewById(R.id.btStart);
holder.stop = (Button)row.findViewById(R.id.btStop);
row.setTag(holder);
}else{
holder = (ViewHolder)row.getTag();
}
holder.start.setEnabled(true);
holder.stop.setEnabled(false);
holder.name.setText(tracker.getName());
final Runnable updateTimeThread = new Runnable() {
#Override
public void run() {
updateTimeList.set(position, (System.currentTimeMillis() - startTime.get(position)) + lastPauseList.get(position));
secondsList.set(position, updateTimeList.get(position) / 1000);
minutesList.set(position, secondsList.get(position) / 60);
hoursList.set(position, minutesList.get(position) / 60);
secondsList.set(position, (secondsList.get(position) % 60));
minutesList.set(position, (minutesList.get(position) % 60));
hoursList.set(position, (hoursList.get(position) % 24));
holder.days.setText(String.format("%04d", daysList.get(position)));
holder.hours.setText(String.format("%02d", hoursList.get(position)));
holder.minutes.setText(String.format("%02d", minutesList.get(position)));
holder.seconds.setText(String.format("%02d", secondsList.get(position)));
handler.postDelayed(this, 0);
}
};
if(isItStart.get(position)){
holder.stop.setEnabled(true);
holder.start.setEnabled(false);
handler.postDelayed(updateTimeThread,0);
}
View.OnClickListener onClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btStart:
startTime.set(position,System.currentTimeMillis());
handler.post(updateTimeThread);
holder.start.setEnabled(false);
holder.stop.setEnabled(true);
isItStart.set(position,true);
break;
case R.id.btStop:
lastPauseList.set(position, updateTimeList.get(position));
handler.removeCallbacks(updateTimeThread);
holder.stop.setEnabled(false);
holder.start.setEnabled(true);
isItStart.set(position,false);
break;
}
}
};
holder.start.setOnClickListener(onClickListener);
holder.stop.setOnClickListener(onClickListener);
return row;
}
class ViewHolder{
TextView name,days,hours,minutes,seconds;
Button start,stop;
}
}
String getTime(long time){
int hours = (int)(time/3600000);
int minutes = (int)(time -hours*3600000)/60000;
int seconds = (int)(time-hours*3600000-minutes*60000)/1000;
String hour = (hours<9?"0"+hours:hours).toString();
String min = (minutes<9?"0"+minutes:minutes).toString();
String sec = (seconds<9?"0"+seconds:seconds).toString();
return ""+hour+":"+min+":"+sec;
}
}
Add android:configChanges="orientation|screenSize" in manifest.xml and delete your onRestore and onSaved.
When you rotating the screen the application refresh the activity i had the same kind of problem so i just locked the screen for one way in the android mainifest by
android:screenOrientation="portrait"
found this great answer by:Xion
"you could distinguish the cases of your activity being created for the first time and being restored from savedInstanceState. This is done by overriding onSaveInstanceState and checking the parameter of onCreate.
You could lock the activity in one orientation by adding android:screenOrientation="portrait" (or "landscape") to in your manifest.
You could tell the system that you meant to handle screen changes for yourself by specifying android:configChanges="orientation" in the tag. This way the activity will not be recreated, but will receive a callback instead (which you can ignore as it's not useful for you)."

Categories

Resources