I have tried to make an countdown timer in a list veiw implementation. Each list item has a separate countdown timer that can be started or stopped. However I have noticed that if I add the first timer in list and set its time. When I start the timer it starts two seconds less than the actual time. e.g If I added a count down of 12 seconds. Then it will start counting from 10. But when the countdown is taking place and I add another new timer and set its time, it starts on the exact given time. The new counter starts at the wrong time only when either there is no other counter in the list or when all counters are already stopped and not counting down. Similarly it will only start the right time only when other timers are counting down. Would really appreciate if someone can help me figure out where is the problem. I have been looking at the code for days.
Here's my Adapter class
public class CustomAdapterCounter extends ArrayAdapter<CounterData> {
private final LayoutInflater mInflater;
Context context;
Uri sound = Uri.parse("android.resource://com.tattooalarmclock.free/" + R.raw.counter);
String counterString = "";
private List<ViewHolder> lstHolders;
private List<CounterData> list = new ArrayList<CounterData>();
private Handler mHandler = new Handler();
private Runnable updateRemainingTimeRunnable = new Runnable() {
#Override
public void run() {
synchronized (lstHolders) {
long currentTime = System.currentTimeMillis();
for (ViewHolder holder : lstHolders) {
// if(!holder.counterData.isStopped)
holder.updateTimeRemaining(System.currentTimeMillis());
}
}
}
};
public CustomAdapterCounter(Context context, List<CounterData> l) {
super(context, 0, l);
this.context = context;
lstHolders = new ArrayList<>();
list = l;
mInflater = LayoutInflater.from(context);
for(int i=0; i<list.size(); i++) {
CounterData[] array = list.toArray(new CounterData[list.size()]);
if(!array[i].isStopped)
startUpdateTimer();
}
}
public double getScreenSize() {
DisplayMetrics dm = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
int dens = dm.densityDpi;
double wi = (double) width / (double) dens;
double hi = (double) height / (double) dens;
double x = Math.pow(wi, 2);
double y = Math.pow(hi, 2);
double screenInches = Math.sqrt(x + y);
return screenInches;
}
private void startUpdateTimer() {
Timer tmr = new Timer();
tmr.schedule(new TimerTask() {
#Override
public void run() {
mHandler.post(updateRemainingTimeRunnable);
}
}, 1000, 1000);
}
public static <T> List<T> stringToArray(String s, Class<T[]> clazz) {
T[] arr = new Gson().fromJson(s, clazz);
return Arrays.asList(arr); //or return Arrays.asList(new Gson().fromJson(s, clazz)); for a one-liner
}
public boolean getListSharedPreferences() {
SharedPreferences sharedPreferences = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
if (sharedPreferences.getString("CL", null) != null) {
counterString = sharedPreferences.getString("CL", null);
Gson gson = new Gson();
TypeToken<List<CounterData>> token = new TypeToken<List<CounterData>>() {};
list = gson.fromJson(counterString, token.getType());
return true;
}
else
return false;
}
public void saveListSharedPreferences(List counterList) {
Gson gson = new Gson();
counterString = gson.toJson(counterList);
SharedPreferences sharedPreferences = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
sharedPreferences.edit().putString("CL", counterString).commit();
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
if(getScreenSize() <= 4 )
convertView = mInflater.inflate(R.layout.list_view_counter_small, parent, false);
else
convertView = mInflater.inflate(R.layout.list_view_item_counter, parent, false);
holder.counterTextView = (TextView) convertView.findViewById(R.id.counterTextView);
holder.stopCounter = (Button) convertView.findViewById(R.id.counterStopInList);
holder.startCounter = (Button) convertView.findViewById(R.id.counterStartInList);
holder.deleteCounter = (Button) convertView.findViewById(R.id.deleteCounter);
convertView.setTag(holder);
synchronized (lstHolders) {
lstHolders.add(holder);
}
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.setData2(getItem(position));
final ViewHolder finalHolder = holder;
holder.stopCounter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
long store = finalHolder.counterData.expirationTime - System.currentTimeMillis();
finalHolder.counterData.isStopped = true;
finalHolder.counterData.expirationTime = store;
finalHolder.stopCounter.setEnabled(false);
finalHolder.stopCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
finalHolder.startCounter.setEnabled(true);
finalHolder.startCounter.getBackground().setColorFilter(null);
list.set(position, finalHolder.counterData);
saveListSharedPreferences(list);
/* if(getListSharedPreferences()) {
System.out.println("List before change in stop button " + list.toString());
list = stringToArray(counterString, CounterData[].class);
list.set(position, finalHolder.counterData);
System.out.println("List before change in stop button " + list.toString());
saveListSharedPreferences(list);
}
else {
System.out.println(list.toString());
list.set(position, finalHolder.counterData);
System.out.println(list.toString());
saveListSharedPreferences(list);
}
*/
}
});
holder.startCounter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finalHolder.counterData.expirationTime = System.currentTimeMillis() + finalHolder.counterData.expirationTime;
finalHolder.counterData.isStopped = false;
//finalHolder.counterData.expirationTime = System.currentTimeMillis() + finalHolder.counterData.expirationTime;
//finalHolder.setData(finalHolder.counterData);
finalHolder.startCounter.setEnabled(true);
finalHolder.startCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
finalHolder.stopCounter.setEnabled(true);
finalHolder.stopCounter.getBackground().setColorFilter(null);
list.set(position, finalHolder.counterData);
saveListSharedPreferences(list);
startUpdateTimer();
/* if(getListSharedPreferences()) {
list = stringToArray(counterString, CounterData[].class);
System.out.println("List before change in start button " + list.toString());
list.set(position, finalHolder.counterData);
System.out.println("List after change in start button " + list.toString());
saveListSharedPreferences(list);
}
else {
list.set(position, finalHolder.counterData);
saveListSharedPreferences(list);
} */
}
});
final ViewHolder finalHolder1 = holder;
holder.deleteCounter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/* if(finalHolder1.mediaPlayer.isPlaying()) {
finalHolder.mediaPlayer.stop();
// finalHolder.counterData.isSoundPlayedBefore = true;
} */
list.remove(position);
notifyDataSetChanged();
saveListSharedPreferences(list);
}
});
return convertView;
}
}
class ViewHolder {
public TextView counterTextView;
//public List<Long> l;
CounterData counterData;
Button startCounter;
Button stopCounter;
Button deleteCounter;
boolean stop = false;
long timeDiff;
// Context context;
// MediaPlayer mediaPlayer;
// List<CounterData> counterDataList;
public void setData(CounterData item) {
counterData = item;
updateTimeRemaining(System.currentTimeMillis());
}
public void setData2(CounterData item) {
counterData = item;
updateTimeRemaining(System.currentTimeMillis());
}
public void updateTimeRemaining(long currentTime) {
if (!counterData.isStopped) {
timeDiff = counterData.expirationTime - currentTime;
//System.out.println("Time Diff Inside Method " + timeDiff);
if (timeDiff > 0) {
int seconds = (int) (timeDiff / 1000) % 60;
int minutes = (int) ((timeDiff / (1000 * 60)) % 60);
int hours = (int) TimeUnit.MILLISECONDS.toHours(timeDiff);
counterTextView.setText(hours + "H " + minutes + "M " + seconds + "S");
stopCounter.setEnabled(true);
stopCounter.getBackground().setColorFilter(null);
startCounter.setEnabled(false);
startCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
} else {
counterTextView.setText("Times Up");
startCounter.setEnabled(false);
startCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
stopCounter.setEnabled(false);
stopCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
// Vibrator v = (Vibrator) this.context.getSystemService(Context.VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
// v.vibrate(5000);
/* if(!counterData.isSoundPlayedBefore) {
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer.stop();
}
});
counterData.isSoundPlayedBefore = true;
if(findIndex(counterData) != -1) {
int index = findIndex(counterData);
counterDataList.set(index,counterData);
saveListSharedPreferences(counterDataList);
}
} */
}
}
else {
long store = counterData.expirationTime + System.currentTimeMillis() - currentTime;
int seconds = (int) (store / 1000) % 60;
int minutes = (int) ((store / (1000 * 60)) % 60);
int hours = (int) TimeUnit.MILLISECONDS.toHours(store);
counterTextView.setText(hours + "H " + minutes + "M " + seconds + "S");
startCounter.setEnabled(true);
startCounter.getBackground().setColorFilter(null);
stopCounter.setEnabled(false);
stopCounter.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
}
}
}
And here's my CounterData class
class CounterData {
long expirationTime;
boolean isStopped;
boolean isSoundPlayedBefore;
int id;
public CounterData(long expirationTime, int id) {
this.expirationTime = expirationTime;
isStopped = true;
isSoundPlayedBefore = false;
this.id = id;
}
public String toString() {
return String.valueOf("Remaining Time: " + TimeUnit.MILLISECONDS.toMinutes(this.expirationTime) + ":" + TimeUnit.MILLISECONDS.toSeconds(this.expirationTime));
}
public void setCounterID(int id) {
this.id = id;
}
public int getCounterID() {
return this.id;
}
}
And I add the time from number pickers of Hour, Minute and Second.
case R.id.counterStartStopButton:
long hour = TimeUnit.HOURS.toMillis(numberPickerHour.getValue());
long minute = TimeUnit.MINUTES.toMillis(numberPickerMinute.getValue());
long second = TimeUnit.SECONDS.toMillis(numberPickerSecond.getValue());
// if(getListSharedPreferences()) {
if(getCounterIDSharedPreferences()) {
counterID = counterID + 1;
list.add(new CounterData(hour + minute + second, counterID));
saveCounterIDSharedPreferences(counterID);
}
else {
counterID = 1;
list.add(new CounterData(hour + minute + second, counterID));
saveCounterIDSharedPreferences(counterID);
}
UPDATE
Here's the shared preferences code
public void saveCounterIDSharedPreferences(int id) {
SharedPreferences sharedPreferences = this.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
sharedPreferences.edit().putInt("Counter ID123", id).commit();
}
public boolean getCounterIDSharedPreferences() {
SharedPreferences sharedPreferences = this.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
if (sharedPreferences.getInt("Counter ID123", -1) != -1) {
counterID = sharedPreferences.getInt("Counter ID123", -1);
return true;
}
else
return false;
}
What turned out to work for me was changing the timer task as following:
private void startUpdateTimer() {
Timer tmr = new Timer();
tmr.schedule(new TimerTask() {
#Override
public void run() {
mHandler.post(updateRemainingTimeRunnable);
}
}, 500, 500);
}
Related
I'm trying to create an app that shows some questions and EditText fields in front of the each of the question for an answer with CountDownTimer, the problem I have is I'm trying to stop the running CountDownTimer on the last entered answer and save those seconds next to user's name but not sure how? I know questionTimer.cancel() would stop the timer but it has to be done on the last entered answer in last EditText.
This is the MainActivity.java file:
public class MainActivity extends AppCompatActivity {
CountDownTimer questionTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStart = (Button) findViewById(R.id.start);
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setQuestions();
timer();
}
});
}//End of create()
public void timer() {
questionTimer = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
timer = (TextView) findViewById(R.id.timer);
timer.setText("Seconds Remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
timer.setText("Done!");
}
}.start();
}
public void setQuestions() {
ArrayList<Questions> qArrList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
ques = new Questions();
ques.setQuestion("");
qArrList.add(ques);
}
adapter = new AdapterListView(getBaseContext(), R.layout.item_listview, qArrList);
questListView.setAdapter(adapter);
}
}//End of Class
This is the AdapterListView.java file:
public class AdapterListView extends ArrayAdapter<Questions> {
Context mContext;
LayoutInflater inflater;
private ArrayList<Questions> questionsArrayList;
private Questions quesObject;
private ArrayList<String> quesList = new ArrayList<String>();
private int a, b, ab, c, d, cd, e, f, ef, g, h, gh, i, j, ij;
private ArrayList<Integer> answersList = new ArrayList<Integer>();
public AdapterListView(Context context, int resource, ArrayList<Questions> questionsArrayList) {
super(context, resource);
this.mContext = context;
this.setQuestionsArrayList(questionsArrayList);
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_listview, null);
holder = new ViewHolder();
holder.questionTextView = convertView.findViewById(R.id.question);
holder.editText = convertView.findViewById(R.id.ans_edit_text);
holder.imgTrue = convertView.findViewById(R.id.ans_true);
holder.imgFalse = convertView.findViewById(R.id.ans_false);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
quesObject = getQuestionsArrayList().get(position);
int count = 0;
if (position == 0) count = 1;
else if (position == 1) count = 2;
else if (position == 2) count = 3;
else if (position == 3) count = 4;
else if (position == 4) count = 5;
Random rand = new Random();
a = (rand.nextInt(15) + 1);
b = (rand.nextInt(10) + 1);
ab = a + b;
c = (rand.nextInt(15) + 1);
d = (rand.nextInt(10) + 1);
cd = c + d;
e = (rand.nextInt(15) + 1);
f = (rand.nextInt(10) + 1);
ef = e + f;
g = (rand.nextInt(15) + 1);
h = (rand.nextInt(10) + 1);
gh = g + h;
i = (rand.nextInt(15) + 1);
j = (rand.nextInt(10) + 10);
ij = i + j;
quesList.add(a + " + " + b);
quesList.add(c + " + " + d);
quesList.add(e + " + " + f);
quesList.add(g + " + " + h);
quesList.add(i + " + " + j);
getAnswersList().add(ab);
getAnswersList().add(cd);
getAnswersList().add(ef);
getAnswersList().add(gh);
getAnswersList().add(ij);
holder.questionTextView.setText("Q " + count + ": \t" + quesList.get(position));
holder.editText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
if (holder.editText.getText().toString().trim().length() > 0) {
int inputNum = Integer.parseInt(String.valueOf(holder.editText.getText().toString().trim()));
if (getAnswersList().get(position) != inputNum) {
holder.imgFalse.setVisibility(View.VISIBLE);
holder.imgTrue.setVisibility(View.GONE);
} else {
holder.imgTrue.setVisibility(View.VISIBLE);
holder.imgFalse.setVisibility(View.GONE);
}
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
return convertView;
}
#Override
public int getCount() {
return getQuestionsArrayList().size();
}
static class ViewHolder {
TextView questionTextView;
EditText editText;
ImageView imgTrue, imgFalse;
}
}
I have manged to sort this out by setting an int variable against Position and calling this in MainActivity class inside the running Timer. Please see the code below.
public class MainActivity extends AppCompatActivity {
CountDownTimer questionTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStart = (Button) findViewById(R.id.start);
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setQuestions();
timer();
}
});
}//End of create()
public void timer() {
questionTimer = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
timer = (TextView) findViewById(R.id.timer);
timer.setText("Seconds Remaining: " + millisUntilFinished / 1000);
if (adapter.getEndQuiz() == 5) {
questionTimer.cancel();
}
}
public void onFinish() {
timer.setText("Done!");
}
}.start();
}
public void setQuestions() {
ArrayList<Questions> qArrList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
ques = new Questions();
ques.setQuestion("");
qArrList.add(ques);
}
adapter = new AdapterListView(getBaseContext(), R.layout.item_listview, qArrList);
questListView.setAdapter(adapter);
}
}//End of Class
Adapter
public class AdapterListView extends ArrayAdapter<Questions> {
Context mContext;
LayoutInflater inflater;
private ArrayList<Questions> questionsArrayList;
private Questions quesObject;
private ArrayList<String> quesList = new ArrayList<String>();
private int a, b, ab, c, d, cd, e, f, ef, g, h, gh, i, j, ij;
private ArrayList<Integer> answersList = new ArrayList<Integer>();
private int endQuiz = 0;
public AdapterListView(Context context, int resource, ArrayList<Questions> questionsArrayList) {
super(context, resource);
this.mContext = context;
this.setQuestionsArrayList(questionsArrayList);
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_listview, null);
holder = new ViewHolder();
holder.questionTextView = convertView.findViewById(R.id.question);
holder.editText = convertView.findViewById(R.id.ans_edit_text);
holder.imgTrue = convertView.findViewById(R.id.ans_true);
holder.imgFalse = convertView.findViewById(R.id.ans_false);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
quesObject = getQuestionsArrayList().get(position);
int count = 0;
if (position == 0) count = 1;
else if (position == 1) count = 2;
else if (position == 2) count = 3;
else if (position == 3) count = 4;
else if (position == 4) count = 5;
Random rand = new Random();
a = (rand.nextInt(15) + 1);
b = (rand.nextInt(10) + 1);
ab = a + b;
c = (rand.nextInt(15) + 1);
d = (rand.nextInt(10) + 1);
cd = c + d;
e = (rand.nextInt(15) + 1);
f = (rand.nextInt(10) + 1);
ef = e + f;
g = (rand.nextInt(15) + 1);
h = (rand.nextInt(10) + 1);
gh = g + h;
i = (rand.nextInt(15) + 1);
j = (rand.nextInt(10) + 10);
ij = i + j;
quesList.add(a + " + " + b);
quesList.add(c + " + " + d);
quesList.add(e + " + " + f);
quesList.add(g + " + " + h);
quesList.add(i + " + " + j);
getAnswersList().add(ab);
getAnswersList().add(cd);
getAnswersList().add(ef);
getAnswersList().add(gh);
getAnswersList().add(ij);
holder.questionTextView.setText("Q " + count + ": \t" + quesList.get(position));
holder.editText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
if (holder.editText.getText().toString().trim().length() > 0) {
int inputNum = Integer.parseInt(String.valueOf(holder.editText.getText().toString().trim()));
if (getAnswersList().get(position) != inputNum) {
holder.imgFalse.setVisibility(View.VISIBLE);
holder.imgTrue.setVisibility(View.GONE);
} else {
holder.imgTrue.setVisibility(View.VISIBLE);
holder.imgFalse.setVisibility(View.GONE);
}
if(position == 0) setEndQuiz(1);
else if(position == 1) setEndQuiz(2);
else if(position == 2) setEndQuiz(3);
else if(position == 3) setEndQuiz(4);
else if(position == 4) setEndQuiz(5);
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
return convertView;
}
#Override
public int getCount() {
return getQuestionsArrayList().size();
}
static class ViewHolder {
TextView questionTextView;
EditText editText;
ImageView imgTrue, imgFalse;
}
}
In my Recycler View not displaying the item orderwise routinely changing the items for each and every time while running the program.
How to display Order wise the items in Recycler View.
Code:
final CustomLinearLayoutManagercartpage layoutManager = new CustomLinearLayoutManagercartpage(CartItems.this, LinearLayoutManager.VERTICAL, false);
recyleitems.setHasFixedSize(false);
recyleitems.setLayoutManager(layoutManager);
cartadapter = new CartlistAdapter(cart, CartItems.this);
Log.i(String.valueOf(cartadapter), "cartadapter");
recyleitems.setAdapter(cartadapter);
recyleitems.setNestedScrollingEnabled(false);
myView.setVisibility(View.GONE);
cartadapter.notifyDataSetChanged();
Adapter:
public class CartlistAdapter extends RecyclerView.Adapter < CartlistAdapter.ViewHolder > {
private ArrayList < CartItemoriginal > cartlistadp;
private ArrayList < Cartitemoringinaltwo > cartlistadp2;
DisplayImageOptions options;
private Context context;
public static final String MyPREFERENCES = "MyPrefs";
public static final String MYCARTPREFERENCE = "CartPrefs";
public static final String MyCartQtyPreference = "Cartatyid";
SharedPreferences.Editor editor;
SharedPreferences shared,
wishshared;
SharedPreferences.Editor editors;
String pos,
qtyDelete;
String date;
String currentDateandTime;
private static final int VIEW_TYPE_ONE = 1;
private static final int VIEW_TYPE_TWO = 2;
private static final int TYPE_HEADER = 0;
private Double orderTotal = 0.00;
DecimalFormat df = new DecimalFormat("0");
Double extPrice;
View layout,
layouts;
SharedPreferences sharedPreferences;
SharedPreferences.Editor QutId;
boolean flag = false;
public CartlistAdapter() {
}
public CartlistAdapter(ArrayList < CartItemoriginal > cartlistadp, Context context) {
this.cartlistadp = cartlistadp;
this.cartlistadp2 = cartlistadp2;
this.context = context;
options = new DisplayImageOptions.Builder().cacheOnDisk(true).cacheInMemory(true).showImageOnLoading(R.drawable.b2)
.showImageForEmptyUri(R.drawable.b2).build();
if (YelloPage.imageLoader.isInited()) {
YelloPage.imageLoader.destroy();
}
YelloPage.imageLoader.init(ImageLoaderConfiguration.createDefault(context));
}
public int getItemViewType(int position) {
if (cartlistadp.size() == 0) {
Toast.makeText(context, String.valueOf(cartlistadp), Toast.LENGTH_LONG).show();
return VIEW_TYPE_TWO;
}
return VIEW_TYPE_ONE;
}
#Override
public CartlistAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
ViewHolder viewHolder = null;
switch (position) {
case VIEW_TYPE_TWO:
View view2 = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_cart, viewGroup, false);
viewHolder = new ViewHolder(view2, new MyTextWatcher(viewGroup, position));
// return view holder for your placeholder
break;
case VIEW_TYPE_ONE:
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cartitemrow, viewGroup, false);
viewHolder = new ViewHolder(view, new MyTextWatcher(view, position));
// return view holder for your normal list item
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(CartlistAdapter.ViewHolder viewHolder, int position) {
viewHolder.productnames.setText(cartlistadp.get(position).getProductname());
viewHolder.cartalisname.setText(cartlistadp.get(position).getAliasname());
viewHolder.cartprice.setText("Rs" + " " + cartlistadp.get(position).getPrice());
viewHolder.cartdelivery.setText(cartlistadp.get(position).getDelivery());
viewHolder.cartshippin.setText(cartlistadp.get(position).getShippincharge());
viewHolder.cartsellername.setText(cartlistadp.get(position).getSellername());
viewHolder.Error.setText(cartlistadp.get(position).getError());
viewHolder.qty.setTag(cartlistadp.get(position));
viewHolder.myTextWatcher.updatePosition(position);
if (cartlistadp.get(position).getQty() != 0) {
viewHolder.qty.setText(String.valueOf(cartlistadp.get(position).getQty()));
viewHolder.itemView.setTag(viewHolder);
} else {
viewHolder.qty.setText("0");
}
YelloPage.imageLoader.displayImage(cartlistadp.get(position).getProductimg(), viewHolder.cartitemimg, options);
}
#Override
public int getItemCount() {
return cartlistadp.size();
}
public long getItemId(int position) {
return position;
}
public Object getItem(int position) {
return cartlistadp.get(position);
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView productnames, cartalisname, cartprice, cartdelivery, cartshippin, cartsellername, Error, total;
private ImageView cartitemimg;
private ImageButton wishbtn, removebtn;
private LinearLayout removecart, movewishlist;
private CardView cd;
private EditText qty;
private ImageView WishImg;
public MyTextWatcher myTextWatcher;
public ViewHolder(final View view, MyTextWatcher myTextWatcher) {
super(view);
productnames = (TextView) view.findViewById(R.id.cartitemname);
cartalisname = (TextView) view.findViewById(R.id.cartalias);
cartprice = (TextView) view.findViewById(R.id.CartAmt);
cartdelivery = (TextView) view.findViewById(R.id.cartdel);
cartshippin = (TextView) view.findViewById(R.id.shippingcrg);
cartsellername = (TextView) view.findViewById(R.id.cartSellerName);
cartitemimg = (ImageView) view.findViewById(R.id.cartimg);
Error = (TextView) view.findViewById(R.id.error);
this.myTextWatcher = myTextWatcher;
removecart = (LinearLayout) view.findViewById(R.id.removecart);
movewishlist = (LinearLayout) view.findViewById(R.id.movewishlist);
WishImg = (ImageView) view.findViewById(R.id.wishimg);
qty = (EditText) view.findViewById(R.id.quantity);
qty.addTextChangedListener(myTextWatcher);
String pid, qid;
sharedPreferences = view.getContext().getSharedPreferences(MYCARTPREFERENCE, Context.MODE_PRIVATE);
QutId = sharedPreferences.edit();
Log.d("Position checking1 ---", String.valueOf(getAdapterPosition()));
//MyTextWatcher textWatcher = new MyTextWatcher(view,qty);
// qty.addTextChangedListener(new MyTextWatcher(view,getAdapterPosition()));
//qty.addTextChangedListener(textWatcher);
qty.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
qty.setSelection(qty.getText().length());
return false;
}
});
wishshared = view.getContext().getSharedPreferences(MyPREFERENCES, context.MODE_PRIVATE);
editors = view.getContext().getSharedPreferences(MyPREFERENCES, context.MODE_PRIVATE).edit();
shared = view.getContext().getSharedPreferences(MYCARTPREFERENCE, context.MODE_PRIVATE);
editor = view.getContext().getSharedPreferences(MYCARTPREFERENCE, context.MODE_PRIVATE).edit();
cd = (CardView) view.findViewById(R.id.cv);
productnames.setSingleLine(false);
productnames.setEllipsize(TextUtils.TruncateAt.END);
productnames.setMaxLines(2);
//totalPrice();
view.setClickable(true);
// view.setFocusableInTouchMode(true);
removecart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (cartlistadp.size() == 1) {
Intent list = new Intent(v.getContext(), Cart.class);
context.startActivity(list);
((Activity) context).finish();
removeAt(getAdapterPosition());
Log.i(String.valueOf(getPosition()), "item");
Toast.makeText(context, "All items deleted from your WishList", Toast.LENGTH_LONG).show();
} else {
removeAt(getAdapterPosition());
}
}
});
MovewishList();
totalPrice();
}
private void totalPrice() {
int price = 0;
for (int j = 0; j < cartlistadp.size(); j++) {
price += Integer.parseInt(cartlistadp.get(j).getPrice()) * (cartlistadp.get(j).getQty());
String totalprice = String.valueOf(price);
String count = String.valueOf(cartlistadp.size());
CartItems.Totalamt.setText(totalprice);
CartItems.cartcount.setText("(" + count + ")");
CartItems.carttotalcount.setText("(" + count + ")");
}
}
public void removeAt(int positions) {
JSONArray test = new JSONArray();
JSONArray test1 = new JSONArray();
JSONArray test2 = new JSONArray();
JSONArray item = null;
JSONArray itemsQty = null;
test1.put("0");
test2.put("0");
test.put(test1);
test.put(test2);
String channel = shared.getString(Constants.cartid, String.valueOf(test));
pos = cartlistadp.get(getAdapterPosition()).getProductid();
qtyDelete = String.valueOf(cartlistadp.get(getAdapterPosition()).getQty());
try {
JSONArray delteitems = new JSONArray(channel);
itemsQty = delteitems.getJSONArray(0);
item = delteitems.getJSONArray(1);
for (int x = 0; x < itemsQty.length(); x++) {
if (pos.equalsIgnoreCase(itemsQty.getString(x))) {
itemsQty.remove(x);
cartlistadp.remove(positions);
notifyItemRemoved(positions);
notifyItemRangeChanged(positions, cartlistadp.size());
notifyDataSetChanged();
}
}
for (int y = 0; y < item.length(); y++) {
if (qtyDelete.equalsIgnoreCase(item.getString(y)))
item.remove(y);
}
String s = String.valueOf(delteitems);
editor.putString(Constants.cartid, String.valueOf(delteitems));
editor.apply();
} catch (JSONException e) {
e.printStackTrace();
}
}
public void MovewishList() {
movewishlist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (cartlistadp.size() == 1) {
pos = cartlistadp.get(getAdapterPosition()).getProductid();
JSONArray items3;
if (!flag) {
// wishlist.setBackgroundResource(R.drawable.wishnew);
flag = true;
String channel = wishshared.getString(Constants.productid, "['']");
JSONArray items;
String wishitem;
if (TextUtils.isEmpty(channel)) {
items = new JSONArray();
items.put(String.valueOf(pos));
wishitem = String.valueOf(items);
editors.putString(Constants.productid, wishitem);
editors.apply();
removeAt(getAdapterPosition());
Toast.makeText(context, "cartItems", Toast.LENGTH_LONG).show();
flag = false;
} else {
try {
Boolean found = false;
items = new JSONArray(channel);
for (int x = 0; x < items.length(); x++) {
if (pos.equalsIgnoreCase(items.getString(x))) {
found = true;
removeAt(getAdapterPosition());
Toast.makeText(context, "cartItems1", Toast.LENGTH_LONG).show();
}
}
if (!found) {
items.put(String.valueOf(pos));
wishitem = String.valueOf(items);
editors.putString(Constants.productid, wishitem);
removeAt(getAdapterPosition());
Toast.makeText(context, Constants.productid, Toast.LENGTH_LONG).show();
Log.i(Constants.productid, "wishitems");
}
editors.apply();
flag = false;
} catch (JSONException e) {
e.printStackTrace();
}
}
Intent list = new Intent(view.getContext(), Cart.class);
context.startActivity(list);
((Activity) context).finish();
} else {
removeAt(getAdapterPosition());
Intent list = new Intent(view.getContext(), Cart.class);
context.startActivity(list);
((Activity) context).finish();
}
} else {
pos = cartlistadp.get(getAdapterPosition()).getProductid();
if (!flag) {
// wishlist.setBackgroundResource(R.drawable.wishnew);
flag = true;
String channel = wishshared.getString(Constants.productid, "['']");
JSONArray items;
String wishitem;
if (TextUtils.isEmpty(channel)) {
items = new JSONArray();
items.put(String.valueOf(pos));
wishitem = String.valueOf(items);
editors.putString(Constants.productid, wishitem);
editors.apply();
removeAt(getAdapterPosition());
Toast.makeText(context, "cartItems", Toast.LENGTH_LONG).show();
flag = false;
} else {
try {
Boolean found = false;
items = new JSONArray(channel);
for (int x = 0; x < items.length(); x++) {
if (pos.equalsIgnoreCase(items.getString(x))) {
found = true;
removeAt(getAdapterPosition());
}
}
if (!found) {
items.put(String.valueOf(pos));
wishitem = String.valueOf(items);
editors.putString(Constants.productid, wishitem);
removeAt(getAdapterPosition());
Log.i(Constants.productid, "wishitems");
}
editors.apply();
flag = false;
} catch (JSONException e) {
e.printStackTrace();
}
}
} else {
removeAt(getAdapterPosition());
}
}
}
});
}
}
public class InputFilterMinMax implements InputFilter {
private int min, max;
public InputFilterMinMax(int min, int max) {
this.min = min;
this.max = max;
}
public InputFilterMinMax(String min, String max) {
this.min = Integer.parseInt(min);
this.max = Integer.parseInt(max);
}
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString() + source.toString());
if (isInRange(min, max, input))
return null;
} catch (NumberFormatException nfe) {}
return "";
}
private boolean isInRange(int a, int b, int c) {
return b > a ? c >= a && c <= b : c >= b && c <= a;
}
}
private class MyTextWatcher implements TextWatcher {
private View view;
private EditText editText;
private int position;
//private int position;
private MyTextWatcher(View view, int position) {
this.view = view;
this.position = position;
// this.position = adapterPosition;
// cartlistadp.get(position).getQty() = Integer.parseInt((Caption.getText().toString()));
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//do nothing
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
// EditText qtyView = (EditText) view.findViewById(R.id.quantity);
Log.i("editextpostion", String.valueOf(position));
}
public void afterTextChanged(Editable s) {
DecimalFormat df = new DecimalFormat("0");
String qtyString = s.toString();
int quantity = qtyString.equals("") ? 0 : Integer.valueOf(qtyString);
String quty = String.valueOf(quantity);
EditText qtyView = (EditText) view.findViewById(R.id.quantity);
CartItemoriginal product = (CartItemoriginal) qtyView.getTag();
// int position = (int) view.qtyView.getTag();
Log.d("postion is qtytag", "Position is: " + product);
qtyView.setFilters(new InputFilter[] {
new InputFilterMinMax(product.getMinquantity(), product.getMaxquantity())
});
if (product.getQty() != quantity) {
Double currPrice = product.getExt();
Double price = Double.parseDouble(product.getPrice());
int maxaty = Integer.parseInt(product.getMaxquantity());
int minqty = Integer.parseInt(product.getMinquantity());
if (quantity < maxaty) {
extPrice = quantity * price;
} else {
Toast.makeText(context, "Sorry" + " " + " " + "we are shipping only" + " " + " " + maxaty + " " + " " + "unit of quantity", Toast.LENGTH_LONG).show();
}
Double priceDiff = Double.valueOf(df.format(extPrice - currPrice));
product.setQty(quantity);
product.setExt(extPrice);
TextView ext = (TextView) view.findViewById(R.id.CartAmt);
if (product.getQty() != 0) {
ext.setText("Rs." + " " + df.format(product.getExt()));
} else {
ext.setText("0");
}
if (product.getQty() != 0) {
qtyView.setText(String.valueOf(product.getQty()));
} else {
qtyView.setText("");
}
JSONArray test = new JSONArray();
JSONArray test1 = new JSONArray();
JSONArray test2 = new JSONArray();
JSONArray items = null;
JSONArray itemsQty = null;
test1.put("0");
test2.put("0");
test.put(test1);
test.put(test2);
JSONArray listitems = null;
//String Sharedqty= String.valueOf(cartlistadp.get(getAdapterPosition()).getQty());
String channel = (shared.getString(Constants.cartid, String.valueOf(test)));
try {
listitems = new JSONArray(channel);
itemsQty = listitems.getJSONArray(1);
} catch (JSONException e) {
e.printStackTrace();
}
try {
if (itemsQty != null) {
itemsQty.put(position + 1, qtyString);
}
} catch (JSONException e) {
e.printStackTrace();
}
try {
if (listitems != null) {
listitems.put(1, itemsQty);
}
} catch (JSONException e) {
e.printStackTrace();
}
QutId.putString(Constants.cartid, String.valueOf(listitems));
QutId.apply();
Toast.makeText(context, String.valueOf(listitems), Toast.LENGTH_SHORT).show();
totalPrice();
}
return;
}
private void totalPrice() {
int price = 0;
for (int j = 0; j < cartlistadp.size(); j++) {
price += Integer.parseInt(cartlistadp.get(j).getPrice()) * (cartlistadp.get(j).getQty());
String totalprice = String.valueOf(price);
String count = String.valueOf(cartlistadp.size());
CartItems.Totalamt.setText(totalprice);
CartItems.cartcount.setText("(" + count + ")");
CartItems.carttotalcount.setText("(" + count + ")");
}
}
public void updatePosition(int position) {
this.position = position;
}
}
}
Thanks in Advance.
For sorting you need to Collection.sort method of Java and also you need to implement comparable interface for define your comparison.
CartItemoriginal implements Comparable {
public int compareTo(Object obj) { } }
Updated
public class CartItemoriginal implements Comparable<CartItemoriginal > {
private Float val;
private String id;
public CartItemoriginal (Float val, String id){
this.val = val;
this.id = id;
}
#Override
public int compareTo(ToSort f) {
if (val.floatValue() > f.val.floatValue()) {
return 1;
}
else if (val.floatValue() < f.val.floatValue()) {
return -1;
}
else {
return 0;
}
}
#Override
public String toString(){
return this.id;
}
}
and use
Collections.sort(sortList);
I have a situation where I need to show seekbar in every row of recylerview to download the media(Audio). The file is downlaoding successfully but everytime I click the downlaod button , only the last seekbar of the recylerview work not the seekbar associated with the particular row.
This is my adapter from where I am downloading audio
public class ListenTestAdapter extends RecyclerView.Adapter<ListenTestAdapter.MyViewHolder> implements AdapterView.OnItemClickListener, View.OnClickListener, View.OnTouchListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnBufferingUpdateListener {
private static final int DOWNLOAD_THREAD_POOL_SIZE = 1;
private final Handler handler = new Handler();
public TextView testNameTextview, downloadTextView, seekBarTextView;
MyDownloadDownloadStatusListenerV1 myDownloadStatusListener = new MyDownloadDownloadStatusListenerV1();
int downloadId1;
private List<Listen> list = new ArrayList<>();
private Activity context;
private MediaPlayer mediaPlayer;
private SeekBar seekBarProgress;
private int mediaFileLengthInMilliseconds;
private String mp3Url;
private Handler durationHandler = new Handler();
private TextView duration;
private int timeElapsed;
private ThinDownloadManager downloadManager;
private String fileName;
private RetryPolicy retryPolicy ;
private File filesDir ;
private Uri downloadUri ;
private SeekBar seekBar ;
//handler to change seekBarTime
private Runnable updateSeekBarTime = new Runnable() {
public void run() {
//get current position
timeElapsed = mediaPlayer.getCurrentPosition();
//set seekbar progress
//seekbar.setProgress((int) timeElapsed);
//set time remaing
double timeRemaining = mediaFileLengthInMilliseconds - timeElapsed;
duration = (TextView) context.findViewById(R.id.duration);
//222067.0
duration.setText(String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining), TimeUnit.MILLISECONDS.toSeconds((long) timeRemaining) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining))));
//repeat yourself that again in 100 miliseconds
durationHandler.postDelayed(this, 100);
}
};
public ListenTestAdapter(Activity context, List<Listen> list) {
this.list = list;
this.context = context;
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Toast.makeText(context, "You Clciked " + position, Toast.LENGTH_SHORT).show();
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
// buttonPlayPause.setImageResource(R.drawable.button_pause);
durationHandler.postDelayed(updateSeekBarTime, 100);
mediaFileLengthInMilliseconds = mediaPlayer.getDuration();
primarySeekBarProgressUpdater();
}
#Override
public void onClick(View v) {
}
#Override
public void onCompletion(MediaPlayer mp) {
context.findViewById(R.id.mediaPlayerLayout).setVisibility(View.GONE);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_listen_item, parent, false);
// set the view's size, margins, paddings and layout parameters
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
testNameTextview.setText(list.get(position).getPassages());
seekBar.setMax(100);
seekBar.setProgress(0);
downloadManager = new ThinDownloadManager(DOWNLOAD_THREAD_POOL_SIZE);
retryPolicy = new DefaultRetryPolicy();
filesDir = context.getExternalFilesDir(Environment.DIRECTORY_MUSIC);
downloadTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mp3Url = list.get(position).getQuestionGroupFile();
mp3Url = mp3Url.replace(" ", "%20");
if(!"".equals(mp3Url)){
downloadUri = Uri.parse(mp3Url);
fileName = mp3Url.substring(mp3Url.lastIndexOf('/') + 1);
//download audio
downLoadAudio();
}else{
Toast.makeText(context, "Audio is not avialable", Toast.LENGTH_SHORT).show();
}
}
});
}
private void downLoadAudio() {
Uri destinationUri = Uri.parse(filesDir + "/" + fileName);
final DownloadRequest downloadRequest = new DownloadRequest(downloadUri)
.setDestinationURI(destinationUri).setPriority(DownloadRequest.Priority.LOW)
.setRetryPolicy(retryPolicy)
.setDownloadContext("Download1")
.setStatusListener(myDownloadStatusListener);
if (downloadManager.query(downloadId1) == DownloadManager.STATUS_NOT_FOUND) {
fileName = fileName.replace("%20", " ");
downloadId1 = downloadManager.add(downloadRequest);
} else {
Toast.makeText(context, "Please wait....Downloading is in progress", Toast.LENGTH_SHORT).show();
}
}
/**
* Method which updates the SeekBar primary progress by current song playing position
*/
private void primarySeekBarProgressUpdater() {
seekBarProgress.setProgress((int) (((float) mediaPlayer.getCurrentPosition() / mediaFileLengthInMilliseconds) * 100)); // This math construction give a percentage of "was playing"/"song length"
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification, 1000);
}
}
#Override
public int getItemCount() {
return list.size();
}
private String getBytesDownloaded(int progress, long totalBytes) {
//Greater than 1 MB
long bytesCompleted = (progress * totalBytes) / 100;
if (totalBytes >= 1000000) {
return ("" + (String.format("%.1f", (float) bytesCompleted / 1000000)) + "/" + (String.format("%.1f", (float) totalBytes / 1000000)) + "MB");
}
if (totalBytes >= 1000) {
return ("" + (String.format("%.1f", (float) bytesCompleted / 1000)) + "/" + (String.format("%.1f", (float) totalBytes / 1000)) + "Kb");
} else {
return ("" + bytesCompleted + "/" + totalBytes);
}
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(View view) {
super(view);
testNameTextview = (TextView) view.findViewById(R.id.testNameTextview);
downloadTextView = (TextView) view.findViewById(R.id.downloadTextview);
seekBarTextView = (TextView) context.findViewById(R.id.duration);
seekBar = (SeekBar) view.findViewById(R.id.seekBar);
}
}
class MyDownloadDownloadStatusListenerV1 implements DownloadStatusListenerV1 {
#Override
public void onDownloadComplete(DownloadRequest request) {
final int id = request.getDownloadId();
if (id == downloadId1) {
seekBarTextView.setText("Downaloaded" + " Audio: " + fileName + " Completed");
//when download is complete encryption will start
EncryptDownloadedAudio.encrypt(context,mp3Url,fileName);
}
}
#Override
public void onDownloadFailed(DownloadRequest request, final int errorCode, final String errorMessage) {
final int id = request.getDownloadId();
if (id == downloadId1) {
context.runOnUiThread(new Runnable() {
#Override
public void run() {
seekBarTextView.setText("Failed to download: " + fileName + " Failed: ErrorCode " + errorCode + ", " + errorMessage);
seekBar.setProgress(0);
}
});
}
}
#Override
public void onProgress(DownloadRequest request, long totalBytes, long downloadedBytes, int progress) {
int id = request.getDownloadId();
System.out.println("######## onProgress ###### " + id + " : " + totalBytes + " : " + downloadedBytes + " : " + progress);
if (id == downloadId1) {
seekBarTextView.setText("Downloading: " + fileName + ", " + progress + "%" + " " + getBytesDownloaded(progress, totalBytes));
seekBar.setProgress(progress);
}
}
}
}
Check the concept of view tags, that will help you out. basically do a seekbar.setTag("UNIQUE ID FOR EVERY VIEW"); then while updating the seekbar use findViewWithTag("UNIQUE ID FOR PARTICULAR VIEW")
since you are fetching view by id it will only give the last view with that id.
Main goal: android app-messendger for chating with company support.
Task: To impliment timers of waiting response from operator or client in listview.
Trouble: In all listview items rendering one of all timer, and then application is listing some timers for a moment are rendering for correctly result, but when they are overlap.
Visually you can see here: https://drive.google.com/file/d/0B_SjoeZavdZwdXlUQlU3QTVKeG8/view?usp=sharing]1
Code:
public class SessionAdapter extends BaseAdapter {
private static final String TAG = SessionAdapter.class.toString();
List<SessionInterface> sessions = new ArrayList<>();
Context context;
private Message mLastMessage;
private List<ViewHolder> lstHolders;
private Handler mHandler = new Handler();
private Runnable updateRemainingTimeRunnable = new Runnable() {
#Override
public void run() {
synchronized (lstHolders) {
long currentTime = System.currentTimeMillis();
for (ViewHolder holder : lstHolders) {
holder.updateTimeRemaining(currentTime, 0);
}
}
}
};
public SessionAdapter(List<SessionInterface> sessions, Context context) {
this.sessions = sessions;
this.context = context;
lstHolders = new ArrayList<>();
startUpdateTimer();
}
public void updateSessions(List<SessionInterface> sessionInterface) {
this.sessions = sessionInterface;
}
#Override
public int getCount() {
return sessions.size();
}
#Override
public SessionInterface getItem(int position) {
return sessions.get(position);
}
#Override
public long getItemId(int position) {
SessionInterface session = sessions.get(position);
return session.getId();
}
public long getPositionById(long id) {
for (int i = 1; i < sessions.size(); i++) {
long sessionId = getItemId(i);
Log.d(TAG, "getPositionById-i: " + i);
Log.d(TAG, "getPositionById-id: " + id);
Log.d(TAG, "getPositionById-sessionId: " + sessionId);
boolean eq = id == sessionId;
Log.d(TAG, "getPositionById-sessionId==id: " + eq);
if(eq) {
return i;
}
}
return 0;
}
private void startUpdateTimer() {
Timer tmr = new Timer();
tmr.schedule(new TimerTask() {
#Override
public void run() {
mHandler.post(updateRemainingTimeRunnable);
}
}, 1000, 1000);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final SessionInterface session = sessions.get(position);
ViewHolder holder;
mLastMessage = session.getMessages().get(session.getMessages().size() - 1);
if(convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.adapter_sessions, null);
holder.label = (TextView) convertView.findViewById(R.id.label);
holder.sessionTitle = (TextView) convertView.findViewById(R.id.ticket_title);
holder.date = (TextView) convertView.findViewById(R.id.date);
holder.message = (TextView) convertView.findViewById(R.id.comment);
holder.status = (TextView) convertView.findViewById(R.id.status);
holder.chatStatusImage = (ImageView) convertView.findViewById(R.id.ticket_status);
holder.timeRemaining = (TextView) convertView.findViewById(R.id.time_remaining);
convertView.setTag(holder);
synchronized (lstHolders) {
lstHolders.add(holder);
}
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.label.setText("Чат #" + session.getId());
holder.sessionTitle.setText(Helpers.stringLimit(session.getQueue().getName(), 30));
try {
Date jud = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", new Locale("ru")).parse(mLastMessage.getDate());
String targetFormat = new SimpleDateFormat("d MMMM, HH:mm", new Locale("ru")).format(jud);
long milliseconds = jud.getTime();
holder.date.setText(targetFormat);
if(session.getClosedTimeAgo() == null) {
holder.updateTimeRemaining(System.currentTimeMillis(), milliseconds);
holder.timeRemaining.setVisibility(View.VISIBLE);
} else {
holder.timeRemaining.setVisibility(View.GONE);
}
} catch (ParseException e) {
e.printStackTrace();
}
holder.message.setText(Helpers.stringLimit(Helpers.stripLineBreaks(mLastMessage.getText(), " "), 50));
if(session.getIs_closed() == 1) {
holder.setClosed(convertView);
} else {
if(mLastMessage.getSender_type().equals(Constants.CLIENT_TYPE)) {
holder.setClientWaiting(convertView);
} else {
holder.setOperatorWaiting(convertView);
}
}
return convertView;
}
private class ViewHolder {
TextView label;
TextView sessionTitle;
TextView date;
TextView message;
TextView status;
ImageView chatStatusImage;
TextView timeRemaining;
public void updateTimeRemaining(long currentTime, long timeAgo) {
Log.d(TAG, "updateTimeRemaining:\n currentTime - " + currentTime + ";\n timeAgo - " + timeAgo + ";\n timeDiff(currentTime - timeAgo) = " + (currentTime - timeAgo));
Log.d(TAG, "updateTimeRemaining:\n currentTime - " + currentTime + ";\n timeAgo - " + timeAgo + ";\n timeDiff(timeAgo - currentTime) = " + (timeAgo - currentTime));
long timeDiff = currentTime - timeAgo;
if (timeDiff > 0) {
int seconds = (int) (timeDiff / 1000) % 60;
int minutes = (int) ((timeDiff / (1000 * 60)) % 60);
int hours = (int) ((timeDiff / (1000 * 60 * 60)) % 24);
int hourMinutes = hours*60 + minutes;
timeRemaining.setText(hourMinutes + ":" + (seconds < 10 ? "0" + seconds : seconds));
} else {
timeRemaining.setText("Expired!!");
}
}
public void setClosed(View convertView) {
this.status.setText("Закрыто");
this.status.setTextColor(convertView.getResources().getColor(R.color.closedText));
this.chatStatusImage.setImageDrawable(convertView.getResources().getDrawable(R.drawable.chat_status_closed));
}
public void setOperatorWaiting(View convertView) {
this.status.setText("Оператор ожидает ваш ответ");
this.status.setTextColor(convertView.getResources().getColor(R.color.clientColor));
this.timeRemaining.setTextColor(convertView.getResources().getColor(R.color.clientColor));
this.chatStatusImage.setImageDrawable(convertView.getResources().getDrawable(R.drawable.chat_status_client));
}
public void setClientWaiting(View convertView) {
this.status.setText("Ожидается ответ оператора");
this.status.setTextColor(convertView.getResources().getColor(R.color.operatorColor));
this.timeRemaining.setTextColor(convertView.getResources().getColor(R.color.operatorColor));
this.chatStatusImage.setImageDrawable(convertView.getResources().getDrawable(R.drawable.chat_status_operator));
}
}
}
Fooh.. year.. It's was realy not easy..
Here is my resolving.. maybe it will help anobody in future..
import android.content.Context;
import android.os.Handler;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import ru.pinspb.pinsupport.R;
import ru.pinspb.pinsupport.common.Constants;
import ru.pinspb.pinsupport.pojo.Message;
import ru.pinspb.pinsupport.pojo.SessionInterface;
import ru.pinspb.pinsupport.utils.Helpers;
public class SessionAdapter extends RecyclerView.Adapter<SessionAdapter.Holder> {
public interface OnItemClickListener {
void onItemClick(SessionInterface item);
}
private static final String TAG = SessionAdapter.class.toString();
private final OnItemClickListener listener;
List<SessionInterface> sessions = new ArrayList<>();
Context context;
private Message mLastMessage;
private Handler mHandler = new Handler();
public SessionAdapter(List<SessionInterface> sessions, Context context, OnItemClickListener listener) {
this.sessions = sessions;
this.context = context;
this.listener = listener;
}
public void updateSessions(List<SessionInterface> sessionInterface) {
this.sessions = sessionInterface;
}
public int getCount() {
return sessions.size();
}
public SessionInterface getItem(int position) {
return sessions.get(position);
}
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_sessions, null);
return new Holder(v);
}
#Override
public void onBindViewHolder(final Holder holder, int position) {
final SessionInterface session = sessions.get(position);
mLastMessage = session.getMessages().get(session.getMessages().size() - 1);
holder.bind(session, listener);
holder.label.setText("Чат #" + session.getId());
holder.sessionTitle.setText(Helpers.stringLimit(session.getQueue().getName(), 30));
try {
SimpleDateFormat ru = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", new Locale("ru"));
ru.setTimeZone(TimeZone.getTimeZone("GMT+03:00"));
Date jud = ru.parse(mLastMessage.getDate());
String targetFormat = new SimpleDateFormat("d MMMM, HH:mm", new Locale("ru")).format(jud);
final long milliseconds = jud.getTime();
holder.date.setText(targetFormat);
if(session.getClosedTimeAgo() == null) {
startUpdateTimer(new Runnable() {
#Override
public void run() {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Moscow"));
Date currentDate = calendar.getTime();
holder.updateTimeRemaining(currentDate.getTime(), milliseconds);
}
});
// Log.d(TAG, "Sid: " + session.getId() + " ;\nnow: " + System.currentTimeMillis() + ";\n last date: " + mLastMessage.getDate() + "; \nmill: " + milliseconds );
holder.timeRemaining.setVisibility(View.VISIBLE);
} else {
holder.timeRemaining.setVisibility(View.GONE);
}
} catch (ParseException e) {
e.printStackTrace();
}
holder.message.setText(Helpers.stringLimit(Helpers.stripLineBreaks(mLastMessage.getText(), " "), 50));
if(session.getIs_closed() == 1) {
holder.setClosed();
} else {
if(mLastMessage.getSender_type().equals(Constants.CLIENT_TYPE)) {
holder.setClientWaiting();
} else {
holder.setOperatorWaiting();
}
}
}
#Override
public long getItemId(int position) {
SessionInterface session = sessions.get(position);
return session.getId();
}
#Override
public int getItemCount() {
return sessions.size();
}
public long getPositionById(long id) {
for (int i = 1; i < sessions.size(); i++) {
long sessionId = getItemId(i);
boolean eq = id == sessionId;
if(eq) {
return i;
}
}
return 0;
}
private void startUpdateTimer(final Runnable runnable) {
Timer tmr = new Timer();
tmr.schedule(new TimerTask() {
#Override
public void run() {
mHandler.post(runnable);
}
}, 1000, 1000);
}
public static class Holder extends RecyclerView.ViewHolder {
TextView label;
TextView sessionTitle;
TextView date;
TextView message;
TextView status;
ImageView chatStatusImage;
TextView timeRemaining;
public Holder(View itemView) {
super(itemView);
this.label = (TextView) itemView.findViewById(R.id.label);
this.sessionTitle = (TextView) itemView.findViewById(R.id.ticket_title);
this.date = (TextView) itemView.findViewById(R.id.date);
this.message = (TextView) itemView.findViewById(R.id.comment);
this.status = (TextView) itemView.findViewById(R.id.status);
this.chatStatusImage = (ImageView) itemView.findViewById(R.id.ticket_status);
this.timeRemaining = (TextView) itemView.findViewById(R.id.time_remaining);
}
public void updateTimeRemaining(long currentTime, long timeAgo) {
// Log.d(TAG, "updateTimeRemaining:\n currentTime - " + currentTime + ";\n timeAgo - " + timeAgo + ";\n timeDiff(currentTime - timeAgo) = " + (currentTime - timeAgo));
// Log.d(TAG, "updateTimeRemaining:\n currentTime - " + currentTime + ";\n timeAgo - " + timeAgo + ";\n timeDiff(timeAgo - currentTime) = " + (timeAgo - currentTime));
long timeDiff = currentTime - timeAgo;
long seconds = TimeUnit.MILLISECONDS.toSeconds(timeDiff) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeDiff));
String time = String.format("%d:%s",
TimeUnit.MILLISECONDS.toMinutes(timeDiff),
seconds < 10 ? seconds + "0" : String.valueOf(seconds)
);
timeRemaining.setText(time);
}
public void setClosed() {
this.status.setText("closed");
this.status.setTextColor(itemView.getResources().getColor(R.color.closedText));
this.chatStatusImage.setImageDrawable(itemView.getResources().getDrawable(R.drawable.chat_status_closed));
}
public void setOperatorWaiting() {
this.status.setText("some text");
this.status.setTextColor(itemView.getResources().getColor(R.color.clientColor));
this.timeRemaining.setTextColor(itemView.getResources().getColor(R.color.clientColor));
this.chatStatusImage.setImageDrawable(itemView.getResources().getDrawable(R.drawable.chat_status_client));
}
public void setClientWaiting() {
this.status.setText("some text");
this.status.setTextColor(itemView.getResources().getColor(R.color.operatorColor));
this.timeRemaining.setTextColor(itemView.getResources().getColor(R.color.operatorColor));
this.chatStatusImage.setImageDrawable(itemView.getResources().getDrawable(R.drawable.chat_status_operator));
}
public void bind(final SessionInterface item, final OnItemClickListener listener) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(item);
}
});
}
}
}
I want to save my Activity state while I swipe between activities but I cannot. Some things are saved and the others dont. I think it has to do somehow with the gestureListener I'm impementing but I'm not sure.
When I swipe to a different activity and then back to this one - the AsyncTask is still running and the Handler is still updating the GUI, however, the views I have displaying in this activity and the buttons are all in their initial configuration.
what am I doing wrong?
public class Main extends Activity implements OnClickListener,
SimpleGestureListener {
/** Called when the activity is first created. */
static String checkedIN = "";
private int hoursSum;
private int minutesSum;
static int dayIs;
static String madeSoFar = "";
static int hoursCount = 0;
static String formattedSeconds = "";
static String formattedMinutes = "";
public static NumberFormat formatter = new DecimalFormat("#0.00");
static boolean killcheck = false;
static String time = "";
static Handler mHandler;
private boolean clicked = false;
private boolean wasShift = false;
static String startString;
static String finishString;
private SimpleGestureFilter detector;
private Typeface tf, tf2, roboto;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
// **************** Set Fonts **************
roboto = Typeface.createFromAsset(getAssets(), "fonts/robotothin.ttf");
tf = Typeface.createFromAsset(getAssets(), "fonts/Advert.ttf");
tf2 = Typeface.createFromAsset(getAssets(), "fonts/passion.ttf");
// **************** Gesture implementation ************
detector = new SimpleGestureFilter(this, this);
// **************** Date and Time Objects *************
final Date date = new Date();
final Date today = Calendar.getInstance().getTime();
DateFormat DF = new SimpleDateFormat("dd/MM/yyyy");
final String DateInString = DF.format(today);
String myString = DateFormat.getDateInstance().format(date);
final TextView dateDisplay = (TextView) findViewById(R.id.dateDisplay);
dateDisplay.setText(myString);
final DBAdapter DB = new DBAdapter(this);
// ************* Apply custom fonts ***************
TextView Title = (TextView) findViewById(R.id.textView2);
Title.setTypeface(tf);
final TextView Author = (TextView) findViewById(R.id.textView3);
Author.setTypeface(roboto);
TextView Current = (TextView) findViewById(R.id.textView1);
Current.setTypeface(roboto);
DigitalClock DG = (DigitalClock) findViewById(R.id.digitalClock1);
DG.setTypeface(roboto);
TextView dater = (TextView) findViewById(R.id.date);
dater.setTypeface(roboto);
TextView dateDisp = (TextView) findViewById(R.id.dateDisplay);
dateDisp.setTypeface(roboto);
CheckedTextView CV = (CheckedTextView) findViewById(R.id.radioButton1);
CV.setTypeface(roboto);
// *************************************************//
final Button checkIn = (Button) findViewById(R.id.CheckIn);
checkIn.setTypeface(roboto);
CheckedTextView check = (CheckedTextView) findViewById(R.id.radioButton1);
Boolean enable = false;
check.setEnabled(enable);
mHandler = new Handler() {
public void handleMessage(Message msg) {
time = "Time: " + hoursCount + ":" + formattedMinutes + ":"
+ formattedSeconds + " Money: " + madeSoFar;
Author.setText(time);
}
};
// **************** Click Listener for first Check In Button
checkIn.setOnClickListener(new OnClickListener() {
int startHours;
int startMinutes;
int finishHours;
int finishMinutes;
#Override
public void onClick(View v) {
// Check Out
if (clicked == true) {
killcheck = true;
checkedIN = "Check In";
checkIn.setText(checkedIN);
finishHours = Utility.getHoursTime();
finishMinutes = Utility.getMinutesTime();
finishString = Integer.toString(Utility.getHoursTime())
+ ":" + Integer.toString(Utility.getMinutesTime())
+ " -";
clicked = false;
wasShift = true;
hoursSum = finishHours - startHours;
minutesSum = finishMinutes - startMinutes;
// Check In
} else if (clicked == false) {
checkedIN = "Check Out";
checkIn.setText(checkedIN);
killcheck = false;
new ShiftProgress().execute();
startHours = Utility.getHoursTime();
startMinutes = Utility.getMinutesTime();
startString = Integer.toString(Utility.getHoursTime())
+ ":" + Integer.toString(Utility.getMinutesTime())
+ " -";
String s = "In Shift ";
CheckedTextView radio = (CheckedTextView) findViewById(R.id.radioButton1);
radio.setText(s);
clicked = true;
}
}
});
Button addShift = (Button) findViewById(R.id.addShift);
addShift.setTypeface(tf2);
// **************** On click listener for adding a shift
addShift.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (wasShift == true) {
changeDateToString(DateInString);
DB.open();
final Cursor cursor = DB.getAllShifts();
startManagingCursor(cursor);
cursor.moveToLast();
int count = cursor.getPosition();
final int position = count + 2;
cursor.moveToNext();
GregorianCalendar GC = new GregorianCalendar();
DB.addToDBTotal(DateInString, "Money: " + madeSoFar,
hoursSum, minutesSum,
Utility.getDay(GC.get(Calendar.DAY_OF_WEEK)),
position, startString, finishString);
DBAdapter.close();
wasShift = false;
printAny(getApplicationContext(), "Added to Shifts",
Toast.LENGTH_SHORT);
} else {
printAny(getApplicationContext(), "Please Check In First", Toast.LENGTH_SHORT);
}
}
});
}
// **************** METHOD DECLERATIONS ****
public void viewShifts() {
Intent myIntent = new Intent(Main.this, Shifts.class);
startActivity(myIntent);
}
public void changeDateToString(String s) {
Utility.INSTANCE.setDate(s);
}
public void changeDurationToString(String s) {
Utility.INSTANCE.setDuration(s);
}
public void printAny(Context c, CharSequence s, int i) {
Context context = c;
CharSequence text = s;
final int duration = i;
Toast toast = Toast.makeText(context, text, duration);
toast.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER, 0, 0);
toast.show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.exit:
System.exit(1);
DBAdapter.close();
return true;
case R.id.view:
viewShifts();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
#Override
public void onSwipe(int direction) {
Intent intent = new Intent();
switch (direction) {
case SimpleGestureFilter.SWIPE_RIGHT:
intent.setClass(this, Shifts.class);
startActivity(intent);
break;
case SimpleGestureFilter.SWIPE_LEFT:
intent.setClass(this, Shifts.class);
startActivity(intent);
break;
}
}
#Override
public boolean dispatchTouchEvent(MotionEvent me) {
this.detector.onTouchEvent(me);
return super.dispatchTouchEvent(me);
}
#Override
public void onDoubleTap() {
// TODO Auto-generated method stub
}
public class ShiftProgress extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... params) {
int count = 0;
int seconds = 0;
int minutesTime = 0;
int minutesCount = 1;
for (;;) {
if (seconds % 60 == 0) {
minutesTime = count / 60;
seconds = 0;
}
if (seconds < 10) {
formattedSeconds = String.format("%02d", seconds);
}
else if (seconds >= 10) {
formattedSeconds = String.valueOf(seconds);
}
if (minutesTime < 10) {
formattedMinutes = String.format("%02d", minutesTime);
}
else if (minutesTime >= 10) {
formattedMinutes = String.valueOf(minutesTime);
}
if (minutesTime % 60 == 0) {
hoursCount = minutesCount / 60;
minutesTime = 0;
}
double sal = 40;
double SEC = 3600;
double salper = count * (sal / SEC);
madeSoFar = String.valueOf(formatter.format(salper));
try {
mHandler.obtainMessage(1).sendToTarget();
Thread.sleep(1000);
seconds++;
count++;
} catch (InterruptedException e) {
e.printStackTrace();
}
if (killcheck) {
break;
}
}
// int length = count /360;
return null;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(Long result) {
}
}
#Override
public void onSaveInstanceState() {
// TODO Auto-generated method stub
Toast.makeText(this, "Activity state saved", Toast.LENGTH_LONG);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
checkedIN = savedInstanceState.getString("checkIN");
clicked = savedInstanceState.getBoolean("button");
Toast.makeText(this, "Activity state Restored", Toast.LENGTH_LONG);
}
#Override
public void onPause(Bundle b) {
// TODO Auto-generated method stub
b.putString("checkIN", checkedIN);
b.putBoolean("button", clicked);
Toast.makeText(this, "Activity state saved", Toast.LENGTH_LONG);
super.onPause();
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putString("checkIN", checkedIN);
outState.putBoolean("button", clicked);
Toast.makeText(this, "Activity state saved", Toast.LENGTH_LONG);
// etc.
super.onSaveInstanceState(outState);
}
#Override
protected void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Activity is getting killed", Toast.LENGTH_LONG)
.show();
}
}
You should not keep your Async task running in the background when your activity is send to the background. Your activity can be quit at any time so that you wouldn't have a reference to your activity anymore.
Regarding the preservation of state you could have a look at Activity.onRetainNonConfigurationInstance()