StickyListHeadersListView MultiChoiceMode issue - android

I am using the StickyListHeadersListView android library from github for my application. It was working fine. After I implement MultiChoiceMode listener for copying and deleting elements, there is a problem in highlighting of elements.
Whenever I select an element and scroll up and down, some Section Headers are highlighted automatically like shown in the image below
How to avoid this behaviour. Is there any steps I'm missing? Need some hand in resolving the issue.
My Adapter which extends the StickyListHeadersAdapter is given below
public class MessageStickyAdapter extends BaseAdapter implements StickyListHeadersAdapter, SectionIndexer {
private final Context mContext;
private List<Msg> messages;
private int[] mSectionIndices;
private String[] mSectionDates;
private LayoutInflater mInflater;
public MessageStickyAdapter(Context context,List<Msg> listMessages) {
mContext = context;
mInflater = LayoutInflater.from(context);
messages = listMessages;
mSectionIndices = getSectionIndices();
mSectionDates = getSectionDates();
}
private int[] getSectionIndices() {
ArrayList<Integer> sectionIndices = new ArrayList<>();
String lastDate = messages.get(0)._msg_date;
sectionIndices.add(0);
for (int i = 1; i < messages.size(); i++) {
if (!messages.get(i)._msg_date.equalsIgnoreCase(lastDate)) {
Log.d("LastDate,Newdate",lastDate + ',' +messages.get(i)._msg_date);
lastDate = messages.get(i)._msg_date;
sectionIndices.add(i);
}
}
int[] sections = new int[sectionIndices.size()];
for (int i = 0; i < sectionIndices.size(); i++) {
sections[i] = sectionIndices.get(i);
}
Log.d("Sections",String.valueOf(sections.length));
return sections;
}
private String[] getSectionDates() {
String[] dates = new String[mSectionIndices.length];
for (int i = 0; i < mSectionIndices.length; i++) {
dates[i] = messages.get(i)._msg_date;
Log.d("Dates",dates[i]);
}
return dates;
}
#Override
public int getCount() {
return messages.size();
}
#Override
public Object getItem(int position) {
return messages.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.right, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.msgr);
holder.time = (TextView) convertView.findViewById(R.id.tim);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
try {
holder.text.setText(URLDecoder.decode( messages.get(position)._msg_content, "UTF-8"));
holder.text.setTag(messages.get(position).getMsgID());
holder.time.setText(messages.get(position)._msg_time);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return convertView;
}
#Override
public View getHeaderView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
if (convertView == null) {
holder = new HeaderViewHolder();
convertView = mInflater.inflate(R.layout.date_separator, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.textSeparator);
convertView.setTag(holder);
} else {
holder = (HeaderViewHolder) convertView.getTag();
}
String headerText = messages.get(position)._msg_date;
holder.text.setText(headerText);
return convertView;
}
/**
* Remember that these have to be static, postion=1 should always return
* the same Id that is.
*/
#Override
public long getHeaderId(int position) {
// return the first character of the country as ID because this is what
// headers are based upon
return getSectionForPosition(position);
}
#Override
public int getPositionForSection(int section) {
if (mSectionIndices.length == 0) {
return 0;
}
if (section >= mSectionIndices.length) {
section = mSectionIndices.length - 1;
} else if (section < 0) {
section = 0;
}
return mSectionIndices[section];
}
#Override
public int getSectionForPosition(int position) {
for (int i = 0; i < mSectionIndices.length; i++) {
if (position < mSectionIndices[i]) {
return i - 1;
}
}
return mSectionIndices.length - 1;
}
#Override
public Object[] getSections() {
return mSectionDates;
}
public void clear() {
messages.clear();
mSectionIndices = new int[0];
mSectionDates = new String[0];
notifyDataSetChanged();
}
public void restore(List<Msg> newMessages)
{
messages.clear();
mSectionIndices = new int[0];
mSectionDates = new String[0];
messages = newMessages;
mSectionIndices = getSectionIndices();
mSectionDates = getSectionDates();
notifyDataSetChanged();
}
public void add(Msg newMessage)
{
messages.add(0,newMessage);
mSectionIndices = getSectionIndices();
mSectionDates = getSectionDates();
}
class HeaderViewHolder {
TextView text;
}
class ViewHolder {
TextView text;
TextView time;
}
}

Related

android Listview repeat data while scroll

i have listview with BaseAdapter this is my adapter code
public class MessageAdapter1 extends BaseAdapter {
Context context;
private int auth;
private List<MessageList> mMessages;
private LayoutInflater mInflater;
public MessageAdapter1(Context context, List<MessageList> messages) {
this.mMessages = messages;
this.context = context;
this.session = new SessionManager(context);
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
auth = session.getUserId();
}
#Override
public int getItemViewType(int position) {
int type = -1;
String m = mMessages.get(position).getType();
int user_idx = mMessages.get(position).getUser_id();
if(auth != user_idx && m.equals("message")) type = 1;
else if(auth == user_idx && m.equals("message")) type = 0;
else if(auth != user_idx && m.equals("image")) type = 3;
else if(auth == user_idx && m.equals("image")) type = 4;
//other else if and types .....
return type;
}
#Override
public int getViewTypeCount() {
return 19;
}
#Override
public int getCount() {
return mMessages.size();
}
#Override
public Object getItem(int i) {
return mMessages.get(i);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case MessageList.TYPE_MESSAGE_RIGHT:
convertView = mInflater.inflate(R.layout.right_message, null);
holder.groupMessage = (LinearLayout)convertView.findViewById(R.id.messages);
break;
case MessageList.TYPE_MESSAGE_LEFT:
convertView = mInflater.inflate(R.layout.left_message, null);
holder.groupMessage = (LinearLayout)convertView.findViewById(R.id.messages);
break;
case MessageList.TYPE_ACTION:
convertView = mInflater.inflate(R.layout.typing, null);
holder.Indicator = (AVLoadingIndicatorView)convertView.findViewById(R.id.indicator);
break;
//other case break for other types ..
}
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
setMessage(holder,position);
return convertView;
}
private void setMessage(ViewHolder holder, int position){
MessageList m = mMessages.get(position);
//holder.groupMessage.add ... data
}
public static class ViewHolder {
private LinearLayout groupMessage;
private AVLoadingIndicatorView Indicator;
//more here other
}
}
I search in google and in stackoverflow all solution talk about Override
`getViewTypeCount` and `getItemViewType` and other solution not helped me
i see my code its correct but why its repeat or reorder item when scroll on
ListView
Because your item views appear to change based on the type of items in the list, you cannot cache your viewholder.
Try removing your if (convertView == null) { and accompanying else { statement.

Adding items into ListView in Fragments creates duplicates

This question has been asked so many times, but none of the solutions solved my issue.
I have an activity with two fragments with a viewpager, And each fragment has a listview. Upon moving between tabs my listview's items are repeating.
here is the adapter code.
public class ComboMenuAdapter extends BaseAdapter {
private Context mContext;
private MenuHolder mMenuHolder;
private ArrayList<Integer> index;
public ComboMenuAdapter(Context mContext, ArrayList<Integer> index) {
this.index = index;
this.mContext = mContext;
}
#Override
public int getCount() {
return index.size();
}
#Override
public MenuHolder getItem(int position) {
return DataHandler.getInstance().getData(index.get(position));
}
#Override
public long getItemId(int position) {
return position;
}
private class Holder {
ImageView image;
TextView price, liters, itemnametxt, mAdd_txt, minus, plus, counter;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final Holder mHolder;
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v= vi.inflate(R.layout.combo_meals_adapter, null);
mHolder = new Holder();
mHolder.price = (TextView) v.findViewById(R.id.price);
mHolder.itemnametxt = (TextView) v.findViewById(R.id.itemnametxt);
mHolder.image = (ImageView) v.findViewById(R.id.image);
mHolder.liters = (TextView) v.findViewById(R.id.ml);
mHolder.mAdd_txt = (TextView) v.findViewById(R.id.addtxt);
mHolder.minus = (TextView) v.findViewById(R.id.minus);
mHolder.counter = (TextView) v.findViewById(R.id.count);
mHolder.plus = (TextView) v.findViewById(R.id.plus);
v.setTag(mHolder);
} else {
mHolder = (Holder) v.getTag();
}
mMenuHolder = getItem(position);
mHolder.itemnametxt.setText(mMenuHolder.getItemname());
mHolder.image.setImageResource(R.mipmap.ic_launcher);
mHolder.price.setText(mMenuHolder.getItemprice());
mHolder.counter.setText(mMenuHolder.getItemCount());
return v;
}
}
I am unable to find the mistake, please help me, Thank you in advance.
Here, I am storing the data using DataHandler Class
public class DataHandler {
ArrayList<MenuHolder> listOfItemsFromJson = new ArrayList<MenuHolder>();
private static DataHandler mInstance = null;
static public DataHandler getInstance() {
if (null == mInstance) {
mInstance = new DataHandler();
}
return mInstance;
}
public DataHandler() {
listOfItemsFromJson = new ArrayList<>();
}
public ArrayList<MenuHolder> getListOfItemsFromJson() {
return listOfItemsFromJson;
}
public void clearList() {
listOfItemsFromJson.clear();
}
public void addData(MenuHolder holder) {
listOfItemsFromJson.add(holder);
}
public MenuHolder getData(int position) {
return listOfItemsFromJson.get(position);
}
public void removeData(int position) {
listOfItemsFromJson.remove(getData(position));
}
public void modifyData(MenuHolder holder, int position) {
listOfItemsFromJson.set(position, holder);
}
public int size() {
return listOfItemsFromJson.size();
}
}
Upon onCreateView(), I am placing the data
for (int i = 0; i < DataHandler.getInstance().size(); i++) {
if (DataHandler.getInstance().getData(i).isCombo()) {
DataHandler.getInstance().removeData(i);
}
}
for (int i = 0; i < 3; i++) {
MenuHolder mMenuHolder = new MenuHolder();
mMenuHolder.setItemname(itemNames[i]);
mMenuHolder.setImageName("#mipmap/ic_launcher");
mMenuHolder.setItemCount("0");
mMenuHolder.setItemprice("500");
mMenuHolder.setUserSeleted(false);
mMenuHolder.setCombo(true);
mMenuHolder.setDrinks(false);
mMenuHolder.setBiryani(false);
DataHandler.getInstance().addData(mMenuHolder);
}
index.clear();
for (int i = 0; i < DataHandler.getInstance().size(); i++) {
if (DataHandler.getInstance().getListOfItemsFromJson().get(i).isCombo()) {
index.add(i);
}
}
mCombosAdapter = new ComboMenuAdapter(getActivity(), index);
mlistView.setVisibility(View.VISIBLE);
mlistView.setAdapter(mCombosAdapter);
mlistView.setOnItemClickListener(this);
mMenuHolder = getItem(position);
should be retrieved before setting the data. Move it outside the if/else logic before.
mMenuHolder = getItem(position);
mHolder.itemnametxt.setText(mMenuHolder.getItemname());
mHolder.image.setImageResource(R.mipmap.ic_launcher);
mHolder.price.setText(mMenuHolder.getItemprice());
mHolder.counter.setText(mMenuHolder.getItemCount());
you want to retrieve the item at position before filling up your view
Make sure you clear your adapter before adding new objects to it:
if (!someAdapter.isEmpty())
someAdapter.clear();
someAdapter.addAll(new ArrarList(arrayListContainingUpdatedStuff));
No need for a new adapter allocation, you might lose you reference to the old one and the list might go blank.
Hope this helps.
for this code you get Repeating data may be
for (int i = 0; i < 3; i++)
{
MenuHolder mMenuHolder = new MenuHolder();
mMenuHolder.setItemname(itemNames[i]);
mMenuHolder.setImageName("#mipmap/ic_launcher");
mMenuHolder.setItemCount("0");
mMenuHolder.setItemprice("500");
mMenuHolder.setUserSeleted(false);
mMenuHolder.setCombo(true);
mMenuHolder.setDrinks(false);
mMenuHolder.setBiryani(false);
DataHandler.getInstance().addData(mMenuHolder);
}

How to avoid default text issue in Custom Spinner Android?

i have done custom spinner with custom adapter in it but getting some default text everytime how to avoid this issue everytime it should only display 0th position text on spinner:
CourseAdapter courseAdapter = new CourseAdapter(mContext);
customViewHolder.spinner.setAdapter(courseAdapter);
while CourseAdapter.java
public class CourseAdapter extends BaseAdapter {
public static final String TAG=CourseAdapter.class.getName();
List<String> courses =new ArrayList<>(); // code to get the courses ArrayList
Context context;
private void fillCourses()
{
for(int i =0;i<10;i++)
{
if(i == 0)
{
courses.add("Choose");
}
else
{
courses.add("courses:"+i);
}
}
}
public CourseAdapter(Context context)
{
this.context = context;
fillCourses();
}
#Override
public int getCount() {
return courses.size();
}
#Override
public Object getItem(int position) {
return courses.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolderFilterItem viewHolder;
if (convertView == null) {
Log.d(TAG, "fillCourses size:" + courses.size());
convertView = LayoutInflater.from(context)
.inflate(R.layout.layout_customspinner, parent, false);
viewHolder = new ViewHolderFilterItem();
viewHolder.textView = (TextView) convertView.findViewById(R.id.txtViewFilterItem);
viewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.checkboxFilterItem);
//store the holder with the view.
convertView.setTag(viewHolder);
return convertView;
}
else
{
Log.d(TAG, "convertview != null:" + courses.size());
viewHolder = (ViewHolderFilterItem) convertView.getTag();
}
if(courses != null && courses.size() > 0) {
String itemText = courses.get(position);
if (itemText != null) {
viewHolder.textView.setText(itemText);
viewHolder.checkBox.setChecked(true);
}
if(position == 0)
{
viewHolder.checkBox.setVisibility(View.GONE);
}
}
return convertView;
}
private class ViewHolderFilterItem{
TextView textView;
CheckBox checkBox;}
}[![[why Filter item text with checkbox appearing ?][1]][1]
you have to use courseAdapter.notifyDataSetChanged() after setting customViewHolder.spinner.setAdapter(courseAdapter);
Hope this helps.

Android custom listview View with timer

I have a problem with the list. My list consists of two rows. The first is simply information about the object. When I click on the first item is presented a second row. It has a timer, everything works as expected, but the re-acquired by the time starts ticking faster. I understand that it is necessary to clean the list or am I just doing something wrong. Help me please.
This is my code:
public class MainActivity extends Activity {
ArrayList<Childrens> arrayList = new ArrayList<Childrens>();
ChilndrensAdapter adapter;
ListView listView;
private static Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = MainActivity.this;
final Childrens ls = new Childrens();
arrayList = ls.getListView();
adapter = new ChilndrensAdapter(getApplicationContext(), arrayList);
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (arrayList.get(position).status == false) {
Log.d("True", " True");
adapter.setSelecterIndex(position);
adapter.toggleSelected(new Integer(position));
adapter.startUpdateTimer(position);
adapter.notifyDataSetChanged();
} else if (arrayList.get(position).status == true) {
Log.d("False", " False");
adapter.setSelecterIndex(position);
adapter.toggleSelected(new Integer(position));
adapter.stopUpdateTimer(position);
adapter.notifyDataSetChanged();
}
}
});
}
public static Context getContext() {
return context;
}
}
Adapter:
public class ChilndrensAdapter extends BaseAdapter {
ArrayList<Childrens> arrayList;
Context context;
private LayoutInflater cInflater;
public ArrayList<Integer> selectedIds = new ArrayList<Integer>();
private ArrayList<ViewHolder> lstHolders;
private static final int END = 0;
private static final int START = 1;
Timer tmr = new Timer();
private Handler mHandler = new Handler();
private Runnable updateRemainingTimeRunnable = new Runnable() {
#Override
public void run() {
//Log.d("Runnable","Runnable");
synchronized (lstHolders) {
long currentTime = 0L;
//long currentTime = System.currentTimeMillis();
for (ViewHolder holder : lstHolders) {
holder.updateTimeRemaining(currentTime);
}
}
}
};
public ChilndrensAdapter(Context context, ArrayList<Childrens> arrayList) {
this.context = context;
this.arrayList = arrayList;
this.cInflater = LayoutInflater.from(context.getApplicationContext());
lstHolders = new ArrayList<>();
// startUpdateTimer();
}
public void startUpdateTimer(final int positon) {
arrayList.get(positon).status = true;
tmr.schedule(new TimerTask() {
#Override
public void run() {
//Log.d("tmr","tmr");
mHandler.post(updateRemainingTimeRunnable);
// arrayList.get(positon).time = arrayList.get(positon).time + 1;
}
}, 1000, 1000);
for (int i = 0; i < lstHolders.size(); i++) {
//Log.d("Holders: ","H: "+ i+" " + lstHolders.get(i) +" Size: " + lstHolders.size() + " Time: "+arrayList.get(positon).time);
}
}
public void stopUpdateTimer(int position) {
arrayList.get(position).time = 0;
arrayList.get(position).status = false;
// Log.d("Timer Run:", "Time is:" + lstHolders.size());
}
#Override
public int getCount() {
if (arrayList == null) {
return 0;
}
return arrayList.size();
}
public void setSelecterIndex(int ind) {
notifyDataSetChanged();
}
public void toggleSelected(Integer position) {
if (selectedIds.contains(position)) {
selectedIds.remove(position);
} else {
selectedIds.add(position);
}
}
#Override
public int getItemViewType(int position) {
if (selectedIds.contains(position)) {
return 1;
} else
return 0;
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public Childrens getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Childrens item = (Childrens) getItem(position);
int type = getItemViewType(position);
if (convertView == null) {
switch (type) {
case END:
holder = new ViewHolder();
convertView = cInflater.inflate(R.layout.listview_row_normal, parent, false);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.info = (TextView) convertView.findViewById(R.id.name_control);
convertView.setTag(holder);
break;
case START:
holder = new ViewHolder();
convertView = cInflater.inflate(R.layout.listview_row_start, parent, false);
holder.name = (TextView) convertView.findViewById(R.id.name_start);
holder.button = (ImageView) convertView.findViewById(R.id.dialog_button);
holder.holderTimer = (TextView) convertView.findViewById(R.id.answerTime);
convertView.setTag(holder);
synchronized (lstHolders) {
lstHolders.add(holder);
}
break;
}
} else {
holder = (ViewHolder) convertView.getTag();
}
switch (type) {
case END:
holder.name.setText(item.name);
holder.info.setText("Time");
break;
case START:
holder.setData(getItem(position));
holder.name.setText(item.name);
holder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Dialog dialog = new Dialog(MainActivity.getContext());
dialog.setTitle("Position " + position);
dialog.setContentView(R.layout.dialog);
dialog.show();
}
});
break;
}
return convertView;
}
public class ViewHolder {
private TextView name;
private TextView info;
public TextView holderTimer;
public ImageView button;
Childrens mChildrens;
public void setData(Childrens item) {
mChildrens = item;
updateTimeRemaining(System.currentTimeMillis());
}
public void updateTimeRemaining(long currentTime) {
int sec = (mChildrens.time) % 60;
int min = (mChildrens.time / 60) % 60;
holderTimer.setText(String.format("%02d", min) + ":" + String.format("%02d", sec));
// holderTimer.setText("Time: " + min +":"+ sec);
}
}
}
Object:
public class Childrens {
public String name;
public int id;
public long answerTime = 0;
public boolean status;
public int time;
final static Childrens CHILDRENS_STATE = new Childrens();
Childrens(String n, int id, long answerTime) {
this.name = n;
this.id = id;
this.answerTime = answerTime;
}
Childrens() {
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public static Childrens getInstance() {
return CHILDRENS_STATE;
}
public ArrayList<Childrens> getListView() {
ArrayList<Childrens> arrayList = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
Childrens c = new Childrens();
c.status = false;
c.name = "Child: " + i;
c.time = 0;
arrayList.add(c);
//arrayList.add(new Childrens("Tata"+ i, i, answerTime));
}
return arrayList;
}
}
Sorry there was mistake in adapter
public class ChilndrensAdapter extends BaseAdapter {
ArrayList<Childrens> arrayList;
Context context;
private LayoutInflater cInflater;
public ArrayList<Integer> selectedIds = new ArrayList<Integer>();
private ArrayList<ViewHolder> lstHolders;
private static final int END = 0;
private static final int START = 1;
Timer tmr = new Timer();
private Handler mHandler = new Handler();
private Runnable updateRemainingTimeRunnable = new Runnable() {
#Override
public void run() {
synchronized (lstHolders) {
for (ViewHolder holder : lstHolders) {
holder.updateTimeRemaining();
}
}
}
};
public ChilndrensAdapter(Context context, ArrayList<Childrens> arrayList){
this.context = context;
this.arrayList = arrayList;
this.cInflater = LayoutInflater.from(context.getApplicationContext());
lstHolders = new ArrayList<>();
}
public void startUpdateTimer(final int positon) {
arrayList.get(positon).status = true;
tmr.schedule(new TimerTask() {
#Override
public void run() {
mHandler.post(updateRemainingTimeRunnable);
arrayList.get(positon).time = arrayList.get(positon).time + 1;
}
}, 1000, 1000);
}
public void stopUpdateTimer(int position) {
arrayList.get(position).time = 0;
arrayList.get(position).status = false;
}
#Override
public int getCount() {
if(arrayList == null){
return 0;
}
return arrayList.size();
}
public void setSelecterIndex(int ind){
notifyDataSetChanged();
}
public void toggleSelected(Integer position){
if (selectedIds.contains(position)){
selectedIds.remove(position);
}else {
selectedIds.add(position);
}
}
#Override
public int getItemViewType(int position) {
if (selectedIds.contains(position)){
return 1;
}else
return 0;
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public Childrens getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Childrens item = (Childrens) getItem(position);
int type = getItemViewType(position);
if(convertView == null){
switch (type){
case END:
holder = new ViewHolder();
convertView = cInflater.inflate(R.layout.listview_row_normal, parent,false);
holder.name = (TextView)convertView.findViewById(R.id.name);
holder.info = (TextView)convertView.findViewById(R.id.name_control);
convertView.setTag(holder);
break;
case START:
holder = new ViewHolder();
convertView = cInflater.inflate(R.layout.listview_row_start, parent, false);
holder.name = (TextView)convertView.findViewById(R.id.name_start);
holder.button = (ImageView)convertView.findViewById(R.id.dialog_button);
holder.holderTimer = (TextView)convertView.findViewById(R.id.answerTime);
convertView.setTag(holder);
synchronized (lstHolders) {
lstHolders.add(holder);
}
break;
}
}else {
holder = (ViewHolder) convertView.getTag();
}
switch (type){
case END:
holder.name.setText(item.name);
holder.info.setText("Time");
break;
case START:
holder.setData(getItem(position));
holder.name.setText(item.name);
holder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Dialog dialog = new Dialog(MainActivity.getContext());
dialog.setTitle("Position " + position);
dialog.setContentView(R.layout.dialog);
dialog.show();
}
});
break;
}
return convertView;
}
public class ViewHolder{
private TextView name;
private TextView info;
public TextView holderTimer;
public ImageView button;
Childrens mChildrens;
public void setData(Childrens item) {
mChildrens = item;
updateTimeRemaining();
}
public void updateTimeRemaining(long currentTime) {
int sec = (mChildrens.time)%60;
int min = (mChildrens.time/60)%60;
holderTimer.setText(String.format("%02d", min) + ":" + String.format("%02d", sec));
}
}
}
I solved the problem and I want to share with you the ready code.
When creating a new timer I dobovlyaet it to your array of, and with the second click on an element and find this timer is reset to zero it. Although at this point I'm going to send data to the server to zero. Generally it works, check!
public class ChilndrensAdapter extends BaseAdapter {
ArrayList<Childrens> arrayList;
Context context;
private LayoutInflater cInflater;
public ArrayList<Integer> selectedIds = new ArrayList<Integer>();
private ArrayList<ViewHolder> lstHolders;
private static final int END = 0;
private static final int START = 1;
Timer tmr;
private Handler mHandler = new Handler();
private Runnable updateRemainingTimeRunnable = new Runnable() {
#Override
public void run() {
synchronized (lstHolders) {
for (ViewHolder holder : lstHolders) {
holder.updateTimeRemaining();
}
}
}
};
public ChilndrensAdapter(Context context, ArrayList<Childrens> arrayList){
this.context = context;
this.arrayList = arrayList;
this.cInflater = LayoutInflater.from(context.getApplicationContext());
lstHolders = new ArrayList<>();
}
public void startUpdateTimer(final int positon) {
arrayList.get(positon).status = true;
tmr = new Timer();
arrayList.get(positon).timer = tmr;
tmr.schedule(new TimerTask() {
#Override
public void run() {
mHandler.post(updateRemainingTimeRunnable);
arrayList.get(positon).time = arrayList.get(positon).time + 1;
}
}, 1000, 1000);
}
public void stopUpdateTimer(int position) {
arrayList.get(position).timer.cancel();
arrayList.get(position).timer = null;
arrayList.get(position).time = 0;
arrayList.get(position).status = false;
}
#Override
public int getCount() {
if(arrayList == null){
return 0;
}
return arrayList.size();
}
public void setSelecterIndex(int ind){
notifyDataSetChanged();
}
public void toggleSelected(Integer position){
if (selectedIds.contains(position)){
selectedIds.remove(position);
}else {
selectedIds.add(position);
}
}
#Override
public int getItemViewType(int position) {
if (selectedIds.contains(position)){
return 1;
}else
return 0;
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public Childrens getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Childrens item = (Childrens) getItem(position);
int type = getItemViewType(position);
if(convertView == null){
switch (type){
case END:
holder = new ViewHolder();
convertView = cInflater.inflate(R.layout.listview_row_normal, parent,false);
holder.name = (TextView)convertView.findViewById(R.id.name);
holder.info = (TextView)convertView.findViewById(R.id.name_control);
convertView.setTag(holder);
break;
case START:
holder = new ViewHolder();
convertView = cInflater.inflate(R.layout.listview_row_start, parent, false);
holder.name = (TextView)convertView.findViewById(R.id.name_start);
holder.button = (ImageView)convertView.findViewById(R.id.dialog_button);
holder.holderTimer = (TextView)convertView.findViewById(R.id.answerTime);
convertView.setTag(holder);
synchronized (lstHolders) {
lstHolders.add(holder);
}
break;
}
}else {
holder = (ViewHolder) convertView.getTag();
}
switch (type){
case END:
holder.name.setText(item.name);
holder.info.setText("Time");
break;
case START:
holder.setData(getItem(position));
holder.name.setText(item.name);
holder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Dialog dialog = new Dialog(MainActivity.getContext());
dialog.setTitle("Position " + position);
dialog.setContentView(R.layout.dialog);
dialog.show();
}
});
break;
}
return convertView;
}
public class ViewHolder{
private TextView name;
private TextView info;
public TextView holderTimer;
public ImageView button;
Childrens mChildrens;
public void setData(Childrens item) {
mChildrens = item;
updateTimeRemaining();
}
public void updateTimeRemaining() {
int sec = (mChildrens.time)%60;
int min = (mChildrens.time/60)%60;
holderTimer.setText(String.format("%02d", min) + ":" + String.format("%02d", sec));
}
}
}

Implement StickyListHeader in ListView with headers

I have a ListView which is having 2 types of headers & within this I want to implement another type of header known as StickyListHeader
Well, Implementing 2 types of header was a complex task for me & now within that implementing StickyListHeader is not an easy task. Let for every 5th view I have to add a StickyListHeader.
This is the code :
public class ContentsFragment extends ListFragment implements OnTouchListener,AbsListView.OnScrollListener {
private MyCustomAdapter mAdapter;
Activity temp = getActivity();
String []s = new String[500];
ArrayList<GS> q = new ArrayList<GS>();
ListView lv;
int count=0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DBAdapter db = DBAdapter.getDBAdapter(getActivity());
if (!db.checkDatabase())
db.createDatabase(getActivity());
db.openDatabase();
q = db.getData();
mAdapter = new MyCustomAdapter(getActivity());
mAdapter.addSeparatorItem(new ContentWrapper(q.get(0).getA_name(),null,null));
mAdapter.addItem(new ContentWrapper(q.get(0).getAS_name(), q.get(0).getDesc_art(),null));
for (int i = 1; i <= 14; i++) {
if (!(q.get(i).getA_name().trim().equals(q.get(i-1).getA_name().trim()))) {
mAdapter.addSeparatorItem(new ContentWrapper(q.get(i).getA_name(), null,null));
}
if(!(q.get(i).getExtra()==null))
mAdapter.addGraySeparatorItem(new ContentWrapper(q.get(i).getExtra(),null,null));
mAdapter.addItem(new ContentWrapper(q.get(i).getAS_name(), q.get(i).getDesc_art(),null));
}
for (int i = 15; i < 36; i++) {
if (!(q.get(i).getA_name().trim().equals(q.get(i-1).getA_name().trim()))) {
mAdapter.addSeparatorItem(new ContentWrapper(q.get(i).getA_name(), null,null));
}
if(!(q.get(i).getExtra()==null))
mAdapter.addGraySeparatorItem(new ContentWrapper(q.get(i).getExtra(),null,null));
mAdapter.addItem(new ContentWrapper(q.get(i).getAS_name(), q.get(i).getDesc_art(),null));
}
//Adapter Class
private class MyCustomAdapter extends BaseAdapter {
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_GRAY_SEPARATOR = 2;
private static final int TYPE_MAX_COUNT = TYPE_GRAY_SEPARATOR + 1;
private TreeSet<Integer> mGraySeparatorsSet = new TreeSet<Integer>();
private ArrayList<ContentWrapper> mData = new ArrayList<ContentWrapper>();
private LayoutInflater mInflater;
private TreeSet<Integer> mSeparatorsSet = new TreeSet<Integer>();
public MyCustomAdapter(Context context)
{
mInflater = LayoutInflater.from(context);
}
public void addItem(ContentWrapper value) {
mData.add(value);
notifyDataSetChanged();
}
public void addSeparatorItem(ContentWrapper value) {
mData.add(value);
// save separator position
mSeparatorsSet.add(mData.size() - 1);
notifyDataSetChanged();
}
public void addGraySeparatorItem(ContentWrapper value) {
mData.add(value);
// save separator position
mGraySeparatorsSet.add(mData.size() - 1);
notifyDataSetChanged();
}
public ContentWrapper getItem(int position) {
return mData.get(position);
}
#Override
public int getItemViewType(int position) {
int viewType = TYPE_ITEM;
if(mSeparatorsSet.contains(position))
viewType = TYPE_SEPARATOR;
else if(mGraySeparatorsSet.contains(position)) {
viewType = TYPE_GRAY_SEPARATOR;
}
return viewType;
// return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}
#Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
public int getCount() {
return mData.size();
}
public long getItemId(int position) {
Log.v("getItemId Position", ""+position);
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.white, null);
holder.textView = (TextView)convertView.findViewById(R.id.text);
break;
case TYPE_SEPARATOR:
convertView = mInflater.inflate(R.layout.black, null);
holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
break;
case 2:
convertView = mInflater.inflate(R.layout.gray, null);
holder.textView = (TextView)convertView.findViewById(R.id.textViewGray);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
} holder.textView.setText(mData.get(position).getItem());
getListView().setFastScrollEnabled(true);
if (type == TYPE_ITEM) {
holder.textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setIcon(R.drawable.ic_launcher);
final String title = mData.get(position).getItem();
builder.setTitle(title);
builder.setMessage(mData.get(position).getItemDescription());
builder.setCancelable(false);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
AlertDialog alertDialog = (AlertDialog) dialog;
ViewGroup viewGroup = (ViewGroup) alertDialog.getWindow()
.getDecorView();
TextView textView = findTextViewWithTitle(viewGroup, title);
if (textView != null) {
textView.setEllipsize(null);
textView.setMaxHeight((int) (100 * alertDialog.getContext().getResources().getDisplayMetrics().density));
textView.setMovementMethod(new ScrollingMovementMethod());
}
}
});
alertDialog.show();
}
private TextView findTextViewWithTitle(ViewGroup viewGroup, String title) {
for (int i = 0, N = viewGroup.getChildCount(); i < N; i++) {
View child = viewGroup.getChildAt(i);
if (child instanceof TextView) {
TextView textView = (TextView) child;
if (textView.getText().equals(title)) {
return textView;
}
} else if (child instanceof ViewGroup) {
ViewGroup vGroup = (ViewGroup) child;
return findTextViewWithTitle(vGroup, title);
}
}
return null;
}
});
}else if(type == 1) {
holder.textView.setOnClickListener(null);
}
else
{
holder.textView.setOnClickListener(null);
}
return convertView;
}
}
public static class ViewHolder {
public TextView textView;
public TextView header;
int previousTop = 0;
}
public boolean onTouch(View v, MotionEvent event) {
return false;
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
//the listview has only few children (of course according to the height of each child) who are visible
for(int i=0; i < getListView().getChildCount(); i++){
View child = getListView().getChildAt(i);
ViewHolder holder = (ViewHolder) child.getTag();
//if the view is the first item at the top we will do some processing
if(i == 0){
boolean isAtBottom = child.getHeight() <= holder.header.getBottom();
int offset = holder.previousTop - child.getTop();
if(!(isAtBottom && offset > 0)){
holder.previousTop = child.getTop();
holder.header.offsetTopAndBottom(offset);
holder.header.invalidate();
}
} //if the view is not the first item it "may" need some correction because of view re-use
else if (holder.header.getTop() != 0) {
int offset = -1 * holder.header.getTop();
holder.header.offsetTopAndBottom(offset);
holder.previousTop = 0;
holder.header.invalidate();
}
}
}
}
As you can see for StickyListHeader I implemented onScroll() method .
Now I think in the modification have to be done in class MyCustomAdapter constructor & in also getView() method beacuse I am follwing this example & it states that we have to deal with constructor,getView() & onScroll().
Can anyone tell me what should I modify to accomplish my task.
Thank You
For Header Listview you should use HeaderListView OR PinnedHeaderListView Library.very easy to use.

Categories

Resources