I am trying to blink listView Custom rows although I am looking for Fade in Fade out animation for listview rows, but in below code I am just changing image after a second and having problem in setting up and accessing background outside listView getViews. I am using Activity and listView is a component in that activity.
Please advice how to access items of listview outside my BaseAdapter in custom method
public class MyView extends Activity implements {
private Timer activeCallBlinker;
MyListAdapter mActiveAdapter;
private class MyListAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private LayoutInflater inflater = null;
ViewHolder viewHolder = null;
public MyListAdapter(Activity act,
ArrayList<HashMap<String, String>> dta) {
activity = act;
data = dta;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
// TODO Auto-generated method stub
View view = null;
if (convertView == null) {
view = inflater.inflate(R.layout.my_listitem, null);
viewHolder = new ViewHolder();
viewHolder.cellBgImg = (ImageView) view.findViewById(R.id.cellBgImage); /// Works fine and setting
view.setTag(viewHolder);
} else {
view = convertView;
}
viewHolder = (ViewHolder) view.getTag();
viewHolder.cellBgImg.setImageResource(R.drawable.stripe_flash);
return view;
}
}
public void populateAndBlink() {
mActiveAdapter = new MyListAdapter(ActiveCallView.this, calledPartyArr);
AnimationAdapter animAdapter = new SwingBottomInAnimationAdapter(mActiveAdapter);
animAdapter.setAbsListView(getListView());
lvActiveCall.setAdapter(animAdapter);
//// After successful population with animation
I am looking to blink it with Fade in Fade out but I can't find a good way so just changing images of background for my listadapter items
activeCallBlinker = new Timer();
startActiveTimer();
}
public void startActiveTimer (){
final int wantedPosition = globalRowIndex;
final Handler handler = new Handler ();
activeCallBlinker.scheduleAtFixedRate (new TimerTask (){
public void run (){
handler.post (new Runnable (){
public void run (){
runOnUiThread(new Runnable() // start actions in UI thread
{
#Override
public void run()
{
View cellView = mActiveAdapter.getView(wantedPosition, null,getListView());
//ViewHolder viewHolder = (ViewHolder) cellView.getTag();
ViewHolder viewHolder = new ViewHolder();
viewHolder.cellBgImg = (ImageView)cellView.findViewById(R.id.cellBgImage);
viewHolder.timerLbl = (TextView)cellView.findViewById(R.id.timerLbl);
if(viewHolder.timerLbl.getVisibility() == View.VISIBLE)
viewHolder.timerLbl.setVisibility(View.INVISIBLE); //// Unable to set InVisibility
else
viewHolder.timerLbl.setVisibility(View.VISIBLE); //// Unable to set Visibility
String resName = getResourceNameFromClassByID(R.drawable.class, R.drawable.stripe);
Log.d("Resource Name", resName);
final Drawable d1 = getResources().getDrawable(R.drawable.stripe);
final Drawable d2 = getResources().getDrawable(R.drawable.strip_header);
if (viewHolder.cellBgImg.getDrawable().equals(d1)) { //// Unable to check Drawable image for setting up background only else is called
Log.d("Resource Name", d1.toString());
viewHolder.cellBgImg.setImageResource(R.drawable.stripe_flash); //// Unable to change image of backkground
} else {
Log.d("Resource Name", d2.toString());
viewHolder.cellBgImg.setImageResource(R.drawable.stripe); //// Unable to change image of backkground
}
}
});
}
});
}
}, 0, 1000);
}
public ListView getListView() {
return lvActiveCall;
}
}
I appreciate pskink comments but Method for taking action on listView need to be called after a minor delay until an unless listView dynamic row addition with animation is completed
Therefore I create a seperate Thread runnable and called my method in it
worker = Executors.newSingleThreadScheduledExecutor();
Runnable myRunnable = createRunnable(i);
worker.schedule(myRunnable, 2, TimeUnit.SECONDS);
private Runnable createRunnable(final int wantedPosition){
Runnable aRunnable = new Runnable(){
public void run(){
runOnUiThread(new Runnable() // start actions in UI
// thread
{
#Override
public void run() {
ApplyActionOnActiveCallsAfterDelay(wantedPosition);
}
}
};
return aRunnable;
}
Related
I am trying to update a textView with timer starting from 00:00:00 every second using Handler. I am also working with custom adapter. So each row has a timer textView,start and stop button. I tried to update the timerTextView in the same row but ended up updating the textView in the last row in the listView.
public class ItemAdapter extends ArrayAdapter<Items>
{
TextView labelTimer;
int passedSeconds = 0;
Boolean isActivityRunning = false;
Timer timer;
TimerTask timerTask;
Context myContext;
int myLayoutResourceID;
Items[] myData = null;
ItemHolder holder = null;
Integer pos;
public ItemAdapter(Context myContext, int myLayoutResourceID, Items[] myData) {
super(myContext,myLayoutResourceID,myData);
this.myContext = myContext;
this.myData = myData;
this.myLayoutResourceID = myLayoutResourceID;
}
#Override
public Items getItem(int position)
{
return super.getItem(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent )
{
View row = convertView;
//ItemHolder holder = null;
if(row == null) {
LayoutInflater inflater = LayoutInflater.from(myContext);
row = inflater.inflate(myLayoutResourceID, parent, false);
holder = new ItemHolder();
holder.nameView = (TextView) row.findViewById(R.id.nameTextView);
holder.timerView = (TextView) row.findViewById(R.id.timerTextView);
holder.imageView = (ImageView) row.findViewById(R.id.imageView);
holder.startButton = (Button) row.findViewById(R.id.startButton);
holder.stopButton = (Button) row.findViewById(R.id.stopButton);
row.setTag(holder);
}
else
{
holder = (ItemHolder) row.getTag();
}
Items item = myData[position];
holder.timerView.setText(item.timer);
final Button srBtn = holder.startButton;
srBtn.setText("START");
//Setup and reuse the same listener each row
Integer rowPosition = position;
pos = position;
holder.startButton.setTag(rowPosition);
holder.timerView.setTag(rowPosition);
final TextView timeV = holder.timerView;
labelTimer = timeV;
labelTimer.setTag(pos);
Log.v("Get tag while creating"+labelTimer.getTag()+" ","");
//Setting the view to reflect the data we need to display
holder.nameView.setText(item.itemName);
int resid = myContext.getResources().getIdentifier(item.itemImage,"drawable",myContext.getPackageName());
holder.imageView.setImageResource(resid);
holder.startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isActivityRunning) {
//pause running activity
timer.cancel();
srBtn.setText("START");
isActivityRunning = false;
} else {
reScheduleTimer();
srBtn.setText("PAUSE");
isActivityRunning = true;
}
}
});
holder.stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
timer.cancel();
passedSeconds = 0;
timeV.setText("00 : 00 : 00");
srBtn.setText("START");
isActivityRunning = false;
}
});
return row;
}
public void reScheduleTimer(){
timer = new Timer();
timerTask = new myTimerTask();
timer.schedule(timerTask, 0, 1000);
}
private class myTimerTask extends TimerTask {
#Override
public void run() {
// TODO Auto-generated method stub
passedSeconds++;
updateLabel.sendEmptyMessage(0);
}
}
private Handler updateLabel = new Handler(){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
//super.handleMessage(msg);
int seconds = passedSeconds % 60;
int minutes = (passedSeconds / 60) % 60;
int hours = (passedSeconds / 3600);
Log.v("Get tag while updating = "+labelTimer.getTag()+" ","");
labelTimer.setText(String.format("%02d : %02d : %02d", hours, minutes, seconds));
}
};
private static class ItemHolder {
TextView nameView;
TextView timerView;
ImageView imageView;
Button startButton;
Button stopButton;
}
}
Can someone explain me how to implement this. The answers which are given are below are not providing me solution.
The Link for similar app is :
https://play.google.com/store/apps/details?id=com.aloggers.atimeloggerapp&hl=en
I see at least few ways. depends on your porouses.
1) Create controller which should be able to access every view created in adapter. holder (in view TAG should have enough information to find codel object for particular view). It also will host one TimerTask. Callback of rimer task should do for each view updating circle.
2) this method used standard listView API with notify data set changed.
I did this same this using inflating rows in main layout, because it is not work well with adapter.
After binding all views, i used handler.
final Handler handler = new Handler();
private void getList() {
// arr_savedeal is my ArrayList
if (arr_savedeal != null) {
lnr_saved_deal.removeAllViews();
for (int i = 0; i < 5; i++) {
// here i am inflating my rows in main layout using linear inflator, same like you did in getView() method of adapter
rowSavedDeal(arr_savedeal.get(i), i);
}
if (arr_savedeal.size() > 0) {
handler.postDelayed(updateTimerThread, 1000); // where 1000 is 1000ms , means its 1s.
}
}
}
private Runnable updateTimerThread = new Runnable() {
#Override
public void run() {
//Do something after 1 second, I am refreshing view here.
getList();
}
};
Try this code. Hope this will help you.
I have an inner class name ThumbnailCreater inside the activity (this activity receives paths of the videos on the external storage from calling activity ) class which work as a grid view builder.
But the problem is it takes little bit long time to load the the activity layout at the time of
1 starting it,
2 coming back to it (thumbnails are clickable and call a new activity to play the clicked thumbnail's video, on pressing back the video playing activity stops but the thumbnail activity don't reappear quickly) and
3 at the time orientation is changed.
class ThumbnailCreater extends BaseAdapter {
ArrayList<String> pathList;
Context context;
public ThumbnailCreater(ArrayList<String> p, Context context) {
this.context = context;
pathList = new ArrayList<String>(p);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return pathList.size();
}
#Override
public Object getItem(int i) {
// TODO Auto-generated method stub
return pathList.get(i);
}
#Override
public long getItemId(int i) {
// TODO Auto-generated method stub
return i;
}
class ViewHolder {
ImageView myVid;
CheckBox picker;
public ViewHolder(View v) {
myVid = (ImageView) v.findViewById(R.id.vid);
picker = (CheckBox) v.findViewById(R.id.checkIt);
}
}
#Override
public View getView(int i, View v, ViewGroup vGroup) {
// TODO Auto-generated method stub
View row = v;
ViewHolder holder = null;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.video_thumbnail, vGroup, false);
holder = new ViewHolder(row);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(pathList.get(i),
MediaStore.Video.Thumbnails.MICRO_KIND);
holder.myVid.setImageBitmap(thumb);
holder.picker.setText(pathList.get(i));
if(vidSelected.contains(holder.picker.getText().toString()))
{
holder.picker.setChecked(true);
}
else
{
holder.picker.setChecked(false);
}
holder.myVid.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewGroup thumbNail = (ViewGroup) v.getParent();
CheckBox checker = (CheckBox) thumbNail.getChildAt(1);
String playIt = checker.getText().toString();
Intent play = new Intent(context, VideoPlay.class);
play.putExtra("playIt", playIt);
context.startActivity(play);
}
});
final CheckBox picker2 = holder.picker;
picker2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (picker2.isChecked()) {
vidSelected.add(picker2.getText().toString());
} else {
for (String s : vidSelected) {
if (s.equals(picker2.getText().toString())) {
vidSelected
.remove(picker2.getText().toString());
break;
}
}
}
}
});
return row;
}
}
I have tried executing grid.setAdapter(new ThumbnailCreater(pathList, this)); as a AsyncTask but failed to achieve the desired resullt.
Is there any way I can load the thumbnails without making delay like for example in web pages images are loaded (randomly or in order) as they are received from the server without creating hindrance in web page scrolling or navigation.
I am working on the quiz application.For that I am using listview for the dispaly the answers options, I want to change the listview background color when user select the listview item, If answer is correct then set the green background and wrong then set red background
I am tring so much, but i don,t get the solution.
Adapter class
public class ListviewAdapter extends BaseAdapter{
public List<String> Questions;
public Activity context;
public LayoutInflater inflater;
private int[] colors = new int[] { 0x30505050, 0x30808080 };
private String[] opt_no;
public static View change_color;
public ListviewAdapter(Activity context,List<String> answers, String[] que_opt_no) {
super();
this.context = context;
this.Questions = answers;
this.opt_no = que_opt_no;
//this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return Questions.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return Questions.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
public static class ViewHolder
{
TextView txtquestion;
TextView txtquestion_no;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
LayoutInflater inflater = context.getLayoutInflater();
// this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
String fontPath = "fonts/Face Your Fears.ttf";
if(convertView==null)
{
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.quiz_questions_listitem, null);
holder.txtquestion = (TextView) convertView.findViewById(R.id.textView_option);
holder.txtquestion_no = (TextView) convertView.findViewById(R.id.textView_option_no);
// holder.txtquestion .setTypeface(Typeface.createFromAsset(convertView.getContext().getAssets(),fontPath));
convertView.setTag(holder);
}
else
holder=(ViewHolder)convertView.getTag();
/* int colorPos = position % colors.length;
convertView.setBackgroundColor(colors[colorPos]); */
change_color = convertView;
// convertView.setBackgroundResource(R.drawable.listview_background);
holder.txtquestion.setText(Questions.get(position));
holder.txtquestion_no.setText(opt_no[position]);
return convertView;
}
/*public static void setbackground(){
String answer = SelectedAnswer.getAnswer();
if (Display_questions.currentQ.getAnswer().trim().equals(answer.trim()))
{
Toast.makeText(change_color.getContext(), "red",Toast.LENGTH_SHORT).show();
change_color.setBackgroundResource(R.drawable.listview_background);
//ListviewAdapter.change_color.setBackgroundResource(R.drawable.listview_background);
//Display_questions.currentGame.incrementRightAnswers();
}
else{
Toast.makeText(change_color.getContext(), "Blue",Toast.LENGTH_SHORT).show();
change_color.setBackgroundResource(R.drawable.listview_false_background);
//Display_questions.currentGame.incrementWrongAnswers();
}
}*/
}
Java class
public class Display_questions extends Activity{
public static Question currentQ;
public static GamePlay currentGame;
ListView listview;
ListviewAdapter adapter;
String que_opt_no[] = {"a) ","b)","c) ","d) "};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.quiz_questions);
listview = (ListView) findViewById(R.id.questions_list);
listview.setItemsCanFocus(false);
GoToNextQuestion();
}
private void GoToNextQuestion() {
// TODO Auto-generated method stub
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> myAdapter, View myView, int pos, long mylng) {
String selectedFromList = (String) listview.getItemAtPosition(pos);
SelectedAnswer.setAnswer(selectedFromList);
if (!checkAnswer(pos)) return;
if (currentGame.isGameOver()){
Intent i = new Intent(Display_questions.this, Display_result.class);
i.putExtra("Timer_Value", TimerTime);
startActivity(i);
finish();
}
else{
GoToNextQuestion();
}
}
});
setQuestions();
}
private void setQuestions() {
// set the question text from current question
String question = currentQ.getQuestion().trim();
TextView qText = (TextView) findViewById(R.id.txt_questions);
qText.setText(question);
// set the available options
List<String> answers = currentQ.getQuestionOptions();
adapter = new ListviewAdapter(this,answers,que_opt_no);
listview.setAdapter(adapter);
}
static boolean checkAnswer(int selectedPosition) {
String answer = SelectedAnswer.getAnswer();
if (answer==null){
return false;
}
else {
AnswerStates state = AnswerStates.NONE;
if (currentQ.getAnswer().trim().equals(answer.trim()))
{
//listview.setBackgroundResource(R.drawable.listview_background);
currentGame.incrementRightAnswers();
state = AnswerStates.RIGHT;
}
else{
//ListviewAdapter.setbackground();
currentGame.incrementWrongAnswers();
state = AnswerStates.WRONG;
}
adapter.setSelectedAnswerState(selectedPosition, state);
adapter.notifyDataSetChanged();
return true;
}
}
}
Edit :
check My images :
1.)
2.)
Do you want to change the background of listview or the selected item when a correct answer is selected.
#Override
public void onItemClick(AdapterView<?> myAdapter, View myView, int pos, long mylng) {
String selectedFromList = (String) listview.getItemAtPosition(pos);
if(selectedFromList.equals("your_answer")) {
// to change the listview background
listview.setBackgroundColor(getResources().getColor(R.color.your_color_id));
// to change the selected item background color
myView.setBackgroundColor(getResources().getColor(R.color.your_color_id));
}
I would suggest to go with the following way:
Adapter class:
add storing of selected position and its state (CORRECT/INCORRECT) or color, e.g.:
public class ListviewAdapter extends BaseAdapter{
enum AnswerStates {
// Colors can be provided also for bg
WRONG(R.drawable.wrong_bg),
RIGHT(R.drawable.right_bg),
NONE(R.drawable.list_item_bg);
/** Drawable id to be used for answer state */
private int mBg;
private AnswerStates(int bg) {
mBg = bg;
}
/** getter for drawabale for answer state */
int getBg() {
return mBg;
}
}
...
/** Position of selected answer */
private int mSelectedPosition = -1;
/** State of selected answer */
private AnswerStates mSelectedAnswerState = AnswerStates.NONE;
...
/** Setter for selected answer */
public void setSelectedAnswerState(int selectedPosition, AnswerStates state) {
mSelectedPosition = selectedPosition;
mSelectedAnswerState = state;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
...
// Your stuff
...
if (position == mSelectedPosition) {
convertView.setBackgroundResource(mSelectedAnswerState.getBg());
} else {
// use default bg
convertView.setBackgroundResource(AnswerStates.NONE.getBg());
}
return convertView;
}
...
}
And Activity class:
public class Display_questions extends Activity{
...
// Added position parameter to the function
static boolean checkAnswer(int selectedPosition) {
//getSelectedAnswer();
String answer = SelectedAnswer.getAnswer();
if (answer==null){
return false;
}
else {
AnswerStates state = AnswerStates.NONE;
if (currentQ.getAnswer().trim().equals(answer.trim()))
{
// here set the background Green color
currentGame.incrementRightAnswers();
state = AnswerStates.RIGHT;
}
else{
// here set the background red color
//ListviewAdapter.setbackground();
currentGame.incrementWrongAnswers();
state = AnswerStates.WRONG;
}
adapter.setSelectedAnswerState(selectedPosition, state);
adapter.notifyDataSetChanged();
return true;
}
}
}
This way is more reliable than another answer, because it will work even if list with answers get scrolled and views get reused by list view.
Problem : in Listview swaps text inside of EditText. it happen when keyboard invisible or visible. as shown in below images.
Code : ListView Activity Class :
public class DayPlannerFormActivity extends Activity {
private TextView txtHeader;
private Context mContext;
private ListView lvDayplannerFrom;
private FormDayPlannerAdapter adapter;
private Activity activity;
final Handler mHandler = new Handler();
private Vector<DayPlannerForm> list = new Vector<DayPlannerForm>();
final Runnable mUpdateResults = new Runnable() {
public void run() {
updateResultsInUi();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dayplanner);
mContext = this;
activity = this;
txtHeader = (TextView) findViewById(R.id.txtHeader);
txtHeader.setText(R.string.haivlate);
lvDayplannerFrom = (ListView) findViewById(R.id.lvDayplanner);
startfetchOperation();
}
private void updateResultsInUi() {
adapter= new FormDayPlannerAdapter(activity,list);
lvDayplannerFrom.setAdapter(adapter);
}
protected void startfetchOperation() {
Thread t = new Thread() {
#Override
public void run() {
getData();
}
};
t.start();
}
private void getData() {
try{
list.clear();
DayPlannerForm dpf = new DayPlannerForm("Task Name 1","","");
list.add(dpf);
dpf =new DayPlannerForm("Task Name 2","","");
list.add(dpf);
mHandler.post(mUpdateResults);
} catch (Exception e){
mHandler.post(mUpdateResults);
}
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
try{
if(lvDayplannerFrom != null)
lvDayplannerFrom.setAdapter(null);
} catch (Exception e){}
}
}
Code : List View Adapter Class
public class FormDayPlannerAdapter extends BaseAdapter {
private Activity mActivity;
private static Vector<DayPlannerForm> list;
private static LayoutInflater inflater;
private Context mContext;
public FormDayPlannerAdapter ( Activity _activity,Vector<DayPlannerForm> _list) {
mActivity = _activity;
mContext = _activity;
list = _list;
inflater = (LayoutInflater)mActivity.getSystemService(mActivity.LAYOUT_INFLATER_SERVICE);
}
public static class ViewHolder{
public TextView txtTaskName;
public CheckBox chbAction;
public EditText edtDecription;
}
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi=convertView;
ViewHolder holder;
if(convertView==null){
vi = inflater.inflate(R.layout.dayplanner_listitem_form, null);
holder=new ViewHolder();
holder.txtTaskName=(TextView)vi.findViewById(R.id.txtTaskName);
holder.chbAction = (CheckBox) vi.findViewById(R.id.chbAction);
holder.edtDecription = (EditText) vi.findViewById(R.id.edtDecription);
vi.setTag(holder);
}
else
holder=(ViewHolder)vi.getTag();
holder.txtTaskName.setText(list.get(position).getTaskName());
return vi;
}
}
How to resolve this problem
Problem solve bye Adding android:windowSoftInputMode="adjustPan" this attribute in activity tag in the manifest.xml
On first look i think that problem occurring by the the following code:-
DayPlannerForm dpf = new DayPlannerForm("Task Name 1","","");
list.add(dpf);
dpf =new DayPlannerForm("Task Name 2","","");
list.add(dpf);
You should take different objects of DayPlannerForm Class for each Task Name.
DayPlannerForm dpf1,dpf2;
dpf1 = new DayPlannerForm("Task Name 1","","");
list.add(dpf1);
dpf2 =new DayPlannerForm("Task Name 2","","");
list.add(dpf2);
I think this might solve your problem.
I'm trying to update the TextView within a custom ListView at a set time interval, for example the TextView will update every 200ms however I can't figure out how to do this. The object updates with a number internally and I would like to show that in the mTitleText Textview however as the code below shows at the moment I can only achieve it when the user presses a button.
public class ListAdapter extends BaseAdapter {
private ArrayList< Object > mObjects;
private int mNumObjs = 0;
private LayoutInflater mLayoutInflater;
private Context mContext;
public ListAdapter ( Context context, ArrayList< Object > objects ) {
mObjects;= objects;
mLayoutInflater = LayoutInflater.from(context);
mContext = context;
}
public int getCount() {
return mObjects;.size();
}
public Object getItem( int position ) {
return mObjects;.get(position);
}
public long getItemId( int position ) {
return position;
}
public void addObject( Object obj) {
obj.setId(mNumObjs);
mObjects.add( obj );
(mNumObjs);++;
notifyDataSetChanged();
}
public void deleteObject( int pos ) {
mObjects;.remove( pos );
notifyDataSetChanged();
}
public View getView( final int position, View convertView, ViewGroup parent ) {
final TimerView holder;
if( convertView == null ) {
convertView = mLayoutInflater.inflate( R.layout.customlistview, null );
holder = new HolderView();
holder.mListPosition = position;
holder.mDeleteButton = (Button)convertView.findViewById(R.id.Delete);
holder.mDeleteButton.setText( "Button No: " + position );
holder.mDeleteButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
deleteObject(holder.mListPosition);
}
});
holder.mButton = (Button)convertView.findViewById(R.id.Button);
holder.mButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Object obj = mObjects.get(holder.mListPosition);
mTitleText.setText(obj.getNum());
}
});
convertView.setTag(holder);
}
else {
holder = (TimerView) convertView.getTag();
}
holder.mListPosition = position;
holder.mDeleteButton.setText( "Button No: " + position );
return convertView;
}
class HolderView{
int mListPosition;
Button mDeleteButton;
Button mButton;
TextView mTitleText;
}
}
Okay I managed to figure this out myself, if your updates don't need to be very frequent ( >1 sec ) you can use notifyDataSetChanged() however if like me you need to constantly update the listview every 200ms or so you need to iterate through the visible objects on the list view and update it.
private Runnable showUpdate = new Runnable(){
public void run(){
mAdapter.updateList();
//mAdapter.notifyDataSetChanged();
int count = mListView.getCount();
for( int i = 0; i < count; i ++ )
{
View convertView = mListView.getChildAt( i );
if( convertView != null )
{
HolderView holder = (HolderView) convertView.getTag();
Object obj = (Object)mAdapter.getItem( holder.mListPosition );
holder.mTitleText.setText( obj.getText() );
}
}
}
};
Thread mThread = new Thread()
{
#Override
public void run() {
try {
while(true) {
sleep(100);
mHandler.post(showUpdate);
//mHandler.sendEmptyMessage(MSG_UPDATE);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Update the text in your list mObjects and call notifyDataSetChanged() on your adapter.