I know that this question is asked many times but i can't seem to make it work in my app
I create custom adapter that extends BaseAdapter, and inside it I put listener of drag and drop function to rearrange the order of the items on the list.
so I need to call notifydatasetchanged when drop action is performed, and I did, but don't seem to reorder the data even though when I print out the data to LogCat is already sorted the way I want it.
I try recommendation like using asyncTask, Activity.runOnUIThread but no result for me. I also that's not very suitable for me since i calling it inside the adapter itself, though I called it from another class inside the adapter.
The data for my adapter I provide inside the adapter itself, get from local DB.
Please help me and take a look at my code:
CategoryAdapter -> customAdapter
public class CategoryAdapter extends BaseAdapter {
private static final String TAG = CategoryAdapter.class.getSimpleName();
private List<CategoryUIO> categoryUIOs;
private Context context;
private LayoutInflater inflater;
private CategorySequenceComparator comparator = new CategorySequenceComparator();
public CategoryAdapter(Activity activity) {
this.context = activity;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
getData();
}
private void getData() {
Cursor cursor = MoneyTracker.getCategoryDB().queryAll();
categoryUIOs = new ArrayList<CategoryUIO>();
if (cursor != null && cursor.moveToFirst()) {
do {
CategoryUIO bo = new CategoryUIO(cursor);
categoryUIOs.add(bo);
} while (cursor.moveToNext());
cursor.close();
}
notifyDataSetChanged();
}
private void sortData() {
if (categoryUIOs != null) {
Collections.sort(categoryUIOs, comparator);
notifyDataSetChanged();
Log.w(TAG, "\n\n");
for (CategoryUIO uio : categoryUIOs) {
Log.w(TAG, Utilities.formatString("Name = %s", uio.getName()));
}
}
}
#Override
public int getCount() {
if (categoryUIOs != null) {
return categoryUIOs.size();
} else {
return 0;
}
}
#Override
public Object getItem(int position) {
if (categoryUIOs != null) {
return categoryUIOs.get(position);
} else {
return null;
}
}
#Override
public long getItemId(int position) {
if (categoryUIOs != null) {
return ((CategoryUIO) getItem(position)).getId();
} else {
return -1;
}
}
public void refresh() {
getData();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
v = inflater.inflate(R.layout.row_list, parent, false);
CategoryUIO uio = ((CategoryUIO) getItem(position));
v.setTag(uio);
if (uio != null) {
final TextView tvItem = (TextView) v.findViewById(R.id.tvItem);
final ImageView ivMove = (ImageView) v.findViewById(R.id.ivMove);
final ImageView ivSecured = (ImageView) v.findViewById(R.id.ivSecured);
tvItem.setText(uio.getDisplayName());
v.setOnDragListener(new MyDragListener());
ivMove.setOnTouchListener(new MyTouchListener());
if (uio.isSecured()) {
ivSecured.setVisibility(ImageView.VISIBLE);
} else {
ivSecured.setVisibility(ImageView.INVISIBLE);
}
}
} else {
}
return v;
}
private final class MyTouchListener implements OnTouchListener {
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
View parent = (View) view.getParent();
CategoryUIO uio = (CategoryUIO) parent.getTag();
ClipData data = ClipData.newPlainText("label", uio.getDisplayName());
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(parent);
// shadowBuilder.onProvideShadowMetrics(new Point(parent.getWidth() / 2, parent.getHeight() / 2), new Point(0, 0));
view.startDrag(data, shadowBuilder, parent, 0);
// view.setVisibility(View.INVISIBLE);
return true;
} else {
return false;
}
}
}
private final class MyDragListener implements OnDragListener {
#Override
public boolean onDrag(View droppedView, DragEvent event) {
int action = event.getAction();
switch (action) {
case DragEvent.ACTION_DRAG_STARTED: {
return true;
}
case DragEvent.ACTION_DRAG_ENTERED: {
return true;
}
case DragEvent.ACTION_DRAG_EXITED: {
return true;
}
case DragEvent.ACTION_DROP: {
View draggedView = (View) event.getLocalState();
CategoryBO draggedBO = ((CategoryBO) draggedView.getTag());
CategoryBO dropedBO = ((CategoryBO) droppedView.getTag());
// persist the sequence to db
SQLiteDatabase db = MoneyTracker.getDB();
db.beginTransaction();
try {
// swap the sequence
int temp = draggedBO.getSequence();
draggedBO.setSequence(dropedBO.getSequence());
dropedBO.setSequence(temp);
ContentValues cv = new ContentValues();
cv.put(CategoryDB.C_ID, draggedBO.getId());
cv.put(CategoryDB.C_SEQUENCE, draggedBO.getSequence());
Response response1 = CategoryBLService.getInstance().update(cv);
cv = new ContentValues();
cv.put(CategoryDB.C_ID, dropedBO.getId());
cv.put(CategoryDB.C_SEQUENCE, dropedBO.getSequence());
Response response2 = CategoryBLService.getInstance().update(cv);
// TODO: THIS PART IS NOT NECESSARY IF CALL TO NOTIFYDATASETCHANGED WORKS {
// the data is updated but seems like notifydatasetchanged in sortData()
// don't have any effect
// swap the BOs
// CategoryBO tempBO = draggedBO;
// draggedBO = dropedBO;
// dropedBO = tempBO;
//
// droppedView.setTag(dropedBO);
// draggedView.setTag(draggedBO);
//
// // refresh the views
// TextView droppedTvItem = (TextView) droppedView.findViewById(R.id.tvItem);
// droppedTvItem.setText(dropedBO.getDisplayName());
// TextView draggedTvItem = (TextView) draggedView.findViewById(R.id.tvItem);
// draggedTvItem.setText(draggedBO.getDisplayName());
// TODO: } THIS IS THE END OF UNNECESSARY BLOCK
if (response1.isSuccess() && response2.isSuccess()) {
db.setTransactionSuccessful();
sortData();
return true;
} else {
return false;
}
} finally {
db.endTransaction();
}
}
case DragEvent.ACTION_DRAG_ENDED: {
return true;
}
default: {
return true;
}
}
}
}
}
You are messing with your getView's implementation.
if (v == null)
you should only inflate the View you want to fill up with your dataset. I will try something like:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
v = inflater.inflate(R.layout.row_list, parent, false);
final TextView tvItem = (TextView) v.findViewById(R.id.tvItem);
final ImageView ivMove = (ImageView) v.findViewById(R.id.ivMove);
final ImageView ivSecured = (ImageView) v.findViewById(R.id.ivSecured);
}
CategoryUIO uio = ((CategoryUIO) getItem(position));
v.setTag(uio);
if (uio != null) {
tvItem.setText(uio.getDisplayName());
v.setOnDragListener(new MyDragListener());
ivMove.setOnTouchListener(new MyTouchListener());
if (uio.isSecured()) {
ivSecured.setVisibility(ImageView.VISIBLE);
} else {
ivSecured.setVisibility(ImageView.INVISIBLE);
}
}
return v;
}
try
CategoryAdapter. notifyDataSetChanged()
When ever you have to refresh an adapter your should enter his name before notifydatasetchanged();
Related
I am trying to make an application with a ListView that include a Country Flag and name. This is so that the user can click on them and be shown images of the country that they wouldve taken before. However for about 3 seconds when the listview loads if i try to scroll it will sort of glitch and send me back to top. This is the code..
public class CountriesListAdapter extends ArrayAdapter {
private int resource;
private LayoutInflater inflater;
private List<CountryModel> countryModels;
private WeakReference<TextView> selectedCountryIdtxt;
private boolean useFilter;
private WeakReference<ProgressBar> progressBarWeakReference;
public int getSelectedCountryId() {
return selectedCountryId;
}
public void setSelectedCountryId(int selectedCountryId) {
this.selectedCountryId = selectedCountryId;
}
private int selectedCountryId;
public CountriesListAdapter(#NonNull WeakReference<Context> context, int resourceId, WeakReference<TextView> textView, #NonNull List<CountryModel> countryModelList, boolean useFilter, WeakReference<ProgressBar> progressBarWeakReference){
super(context.get(), resourceId, countryModelList);
selectedCountryIdtxt = textView;
resource = resourceId; //the id of the template file
inflater = LayoutInflater.from(context.get());
this.countryModels = countryModelList;
selectedCountryId = -1;
this.useFilter = useFilter;
this.progressBarWeakReference = progressBarWeakReference;
}
public int getCount() {
if (countryModels != null)
return countryModels.size();
return 0;
}
public CountryModel getItem(int position) {
if (countryModels != null)
return countryModels.get(position);
return null;
}
public long getItemId(int position) {
if (countryModels != null)
return countryModels.get(position).hashCode();
return 0;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
// this method is automatically called for every object in our list
//basically it's called for every single row before it is generated
// this method is called per row
convertView = (ConstraintLayout) inflater.inflate(resource, null);
//the variable countryModel is fiiled with current object that is being processed
final CountryModel countryModel = countryModels.get(position);
TextView countryName = convertView.findViewById(R.id.countryNamelbl);
final ImageView countryFlag = convertView.findViewById(R.id.countryFlagimg);
final ImageView checked = convertView.findViewById(R.id.countryCheckedimg);
//this is done for every object in the list
assert countryModel != null;
countryName.setText(countryModel.getName());
Picasso.get().load(countryModel.getImage()).fit().into(countryFlag);
if(!useFilter) {
if (selectedCountryId == countryModel.getId()) {
checked.setVisibility(View.VISIBLE);
} else {
checked.setVisibility(View.INVISIBLE);
}
}
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!useFilter) {
if (checked.getVisibility() == View.VISIBLE) {
checked.setVisibility(View.INVISIBLE);
selectedCountryId = -1;
selectedCountryIdtxt.get().setText(String.valueOf(selectedCountryId));
} else {
if (selectedCountryId == -1) {
checked.setVisibility(View.VISIBLE);
selectedCountryId = countryModel.getId();
} else {
selectedCountryId = countryModel.getId();
notifyDataSetChanged();
}
selectedCountryIdtxt.get().setText(String.valueOf(selectedCountryId));
}
} else {
Intent i = new Intent(getContext(), PicturesActivity.class);
i.putExtra("countryId",countryModel.getId());
i.putExtra("countryName", countryModel.getName());
getContext().startActivity(i);
}
}
});
progressBarWeakReference.get().setVisibility(View.INVISIBLE);
return convertView;
}
public List<CountryModel> getCountryModels() {
return countryModels;
}
public void setCountryModels(List<CountryModel> countryModels) {
this.countryModels = countryModels;
}
}
The problem was actually in another class, i was calling the adapter for every list item instead of just once... oops.
Thanks for the replies though!
I am getting a weird error while setting up my adapter for listview in Android. I am developing a chat application, when i send any message it appears in listview, but when i try to receive the message it takes me to Catch-block in FutureTask class
I am using adapter.notifyDataSetChanged(); to let my adapter know of any change i am creating in the adapter.
My code is as follows
private void addNewMessage(MessageItems m) {
if(MainActivity.mymessage)
{
messages.add(m);
}else if(MainActivity.mymessage == false)
{
messages.add(m);
}
adapter.notifyDataSetChanged();
getListView().setSelection(messages.size()-1);
}
**Code of Adapter**
public class AwesomeAdapter extends BaseAdapter{
private Context mContext;
private ArrayList<MessageItems> mMessages;
public AwesomeAdapter(Context context, ArrayList<MessageItems> messages) {
super();
this.mContext = context;
this.mMessages = messages;
}
#Override
public int getCount() {
return mMessages.size();
}
#Override
public Object getItem(int position) {
return mMessages.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MessageItems message = (MessageItems) this.getItem(position);
ViewHolder holder;
if(convertView == null)
{
holder = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(R.layout.sms_row, parent, false);
holder.message = (TextView) convertView.findViewById(R.id.message_text);
convertView.setTag(holder);
}
else
holder = (ViewHolder) convertView.getTag();
holder.message.setText(message.getMessage());
LayoutParams lp = (LayoutParams) holder.message.getLayoutParams();
//check if it is a status message then remove background, and change text color.
if(message.isStatusMessage())
{
holder.message.setBackgroundDrawable(null);
lp.gravity = Gravity.LEFT;
holder.message.getResources().getColor(R.color.textFieldColor);
//holder.message.setTextColor(R.color.textFieldColor);
}
else
{
//Check whether message is mine to show green background and align to right
if(message.isMine())
{
holder.message.setBackgroundResource(R.drawable.speech_bubble_green);
lp.gravity = Gravity.RIGHT;
}
//If not mine then it is from sender to show orange background and align to left
else
{
holder.message.setBackgroundResource(R.drawable.speech_bubble_orange);
lp.gravity = Gravity.LEFT;
}
holder.message.setLayoutParams(lp);
holder.message.getResources().getColor(R.color.textFieldColor);
//holder.message.setTextColor(R.color.textColor);
}
return convertView;
}
private static class ViewHolder
{
TextView message;
}
#Override
public long getItemId(int position) {
//Unimplemented, because we aren't using Sqlite.
return position;
}
In FutureTask class it takes me to the following try-catch block when i try to set adapter.notifyDataSetChanged();
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
I know the problem somewhere lies in setting up the adapter for listview, i need to update it as i get a new message, but i am unable to get it fixed. Your help would be appreciated
In my Android application, I am using webservices with index values (for eg.
https://mysampleurl.com/sampledata?username=""&&password=""&&startindex="1"&&endindex="10")
and pass the extracted data to a BaseAdapter via an arraylist and display the result in a listview.
When the listview reaches the bottom, Using asynctask I will increment the index values (for eg.
https://mysampleurl.com/sampledata?username=""&&password=""&&startindex="11"&&endindex="20").
I will receive the data and store it in arraylist and it goes on.
But when I pass array list values to adapter, it overwrites the existing data instead of appending with previous values.
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
System.out.println("position:"+position);
}
I have checked this above code in some other examples, at first it gives values like 1,2,.....10. and at second time it gives 1,2,3,.....20. But in my application it always return the values upto 1,2,3......10.
Could some one tell me what mistake I have done?
public ContentListAdapter (Context context, ArrayList<CommonData> contentList)
{
ctxt = context;
this.ContentList = contentList;
contentListRowInflater = LayoutInflater.from(context);
mSelectedItemsIds=new SparseBooleanArray();
checkBoxState=new boolean[contentList.size()];
}
#Override
public int getCount() {
return (filteredContentList == null)?0:filteredContentList.size();
}
#Override
public Object getItem(int position) {
return filteredContentList.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
Here only i pass the values and check the position
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
ContentListActivity.adapterFlag = false;
DocumentListViewHolder viewHolder = null;
if (convertView == null || convertView.getTag() == null) {
convertView = contentListRowInflater.inflate(
R.layout.content_list_row, null);
viewHolder = new DocumentListViewHolder();
viewHolder.ivDocumentdoctypeIcon = (ImageView) convertView.findViewById(R.id.ivDocumentTypeIcon);
viewHolder.tvDocumentTitle = (TextView) convertView.findViewById(R.id.tvDocumentTitle);
viewHolder.tvsubitemcount = (TextView) convertView.findViewById(R.id.tvsubitemcount);
viewHolder.ivarrowlauncher = (ImageView)convertView.findViewById(R.id.arrowlauncher);
viewHolder.checkboxselection=(CheckBox)convertView.findViewById(R.id.checkboxdeletion);
checkBoxSelection=viewHolder.checkboxselection;
viewHolder.checkboxselection.setChecked(checkBoxState[position]);
viewHolder.ivarrowlauncher = (ImageView)convertView.findViewById(R.id.arrowlauncher);
mainlayoutrl = (RelativeLayout)convertView.findViewById(R.id.clrrlmain);
sublayoutll = (LinearLayout)convertView.findViewById(R.id.clrowll);
arrowlayoutll = (LinearLayout)convertView.findViewById(R.id.clarrowll);
final Context context = ContentListActivity.contentListActivity;
if(viewHolder.checkboxselection.isChecked()) {
mainlayoutrl.setBackgroundColor(ctxt.getResources().getColor(R.color.checkboxrowselect));
sublayoutll.setBackgroundColor(ctxt.getResources().getColor(R.color.checkboxrowselect));
arrowlayoutll.setBackgroundColor(ctxt.getResources().getColor(R.color.checkboxrowselect));
} else {
mainlayoutrl.setBackgroundColor(ctxt.getResources().getColor(R.color.white));
sublayoutll.setBackgroundColor(ctxt.getResources().getColor(R.color.white));
arrowlayoutll.setBackgroundColor(ctxt.getResources().getColor(R.color.white));
}
sublayoutll.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (Config.networkConnectionCheck(context)) {
if(filteredContentList.get(position).type.equalsIgnoreCase("FOLDER")) {
ContentListActivity.ListarrowClick(position+1,context);
} else if (refreshFlag == false) {
ContentListActivity.oldviewContent(position+1,context);
} else
} else {
ContentListActivity.oldofflineViewContent(position+1,context);
}
}
});
arrowlayoutll.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
ContentListActivity.ListarrowClick(position+1,context);
}
});
viewHolder.ivfilesDownload=(ImageView)convertView.findViewById(R.id.document_list_row_download_imageview);
//newly added by venkat
viewHolder.ivfilesdownloaded=(ImageView)convertView.findViewById(R.id.document_list_row_downloaded_imageview);
viewHolder.tvDocumentDescription=(TextView)convertView.findViewById(R.id.tvdocumentdescription);
} else {
viewHolder = (DocumentListViewHolder) convertView.getTag();
}
viewHolder.tvDocumentTitle.setText(filteredContentList.get(position).name);
String desc = filteredContentList.get(position).versiondescription;
if (desc != null) {
viewHolder.tvDocumentDescription.setText(filteredContentList
.get(position).versiondescription);
}
String doctype = filteredContentList.get(position).type;
String subitemcount = filteredContentList.get(position).subitemcount;
if (doctype.equalsIgnoreCase(ctxt.getResources()
.getString(R.string.pdf))) {
viewHolder.ivDocumentdoctypeIcon
.setImageResource(R.drawable.pdfbigicon);
} else if (doctype.equalsIgnoreCase(ctxt.getResources().getString(
R.string.swf))) {
viewHolder.ivDocumentdoctypeIcon
.setImageResource(R.drawable.flashbigicon);
} if(doctype.equalsIgnoreCase(ctxt.getResources().getString(
R.string.folder)))
{
viewHolder.ivarrowlauncher.setVisibility(View.INVISIBLE);
}
if (filteredContentList.get(position).isupdateavailable
.equalsIgnoreCase(ctxt.getResources().getString(
R.string.update_false_status))) {
} else if (filteredContentList.get(position).isupdateavailable
.equalsIgnoreCase(ctxt.getResources().getString(
R.string.update_true_status))) {
WebAPI webapi = new WebAPI(ctxt);
if (LoginHandler.arraylistdata.size() == 1) {
user_id = LoginHandler.arraylistdata.get(0)
.getUserid();
org_id = LoginHandler.arraylistdata.get(0)
.getOrgId();
} else {
user_id = LoginHandler.arraylistdata.get(
OrgListActivity.selected_org_pos)
.getUserid();
org_id = LoginHandler.arraylistdata.get(
OrgListActivity.selected_org_pos)
.getOrgId();
}
LoginDatabaseHandler loginDBHandler = new LoginDatabaseHandler(
ctxt);
loginDBHandler.open();
int toglState = loginDBHandler.checkOffToggleState(
user_id, org_id, filteredContentList
.get(position).dockey.toString());
}
} else
versionUpdate(position, ctxt);
}
});
}
/*ends*/
return convertView;
}
When I use listview with adapter which add a gallery in the view and the gallery adapter loads the image loads the image with asynctask the gallery shows in different places.
public View getView(int position, View convertView, ViewGroup parent) {
final int myPosition = position;
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
boolean isConverted = false;
switch(typeOfCell.get(position))
{
case 0:
if(convertView == null)
{
rowView = inflater.inflate(R.layout.newstextcelladapter, parent, false);
}
else
{
rowView = convertView;
}
break;
case 1:
if(convertView == null)
{
rowView = inflater.inflate(R.layout.newsimagecelladapter, parent, false);
}
else
{
rowView = convertView;
isConverted = true;
}
Gallery gallery = (Gallery) rowView.findViewById(R.id.newsImageGallery);
try{
gallery.setAdapter(this.adaptersForGallery.get(position));
Log.w("Adapter used", "" + this.adaptersForGallery.get(position));
Log.w("URL used", "" + this.adaptersForGallery.get(position).mImageIds.get(0));
gallery.setHorizontalFadingEdgeEnabled(false);
gallery.setVisibility(View.GONE);
gallery.setVisibility(View.VISIBLE);
}
catch(Exception e)
{
#SuppressWarnings("unused")
int a =1;
Log.w("FATAL","ERROR");
}
rowView.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
View view2 = new View(MainActivity.context);
DetailsImageNews.setView(MainActivity.dataBase.getCommentsForNews(MainActivity.existingForNews.get(myPosition)),
MainActivity.dataBase.getAuthorForNews(MainActivity.existingForNews.get(myPosition)),
MainActivity.dataBase.getDateForNews(MainActivity.existingForNews.get(myPosition)),
MainActivity.dataBase.getTimeForNews(MainActivity.existingForNews.get(myPosition)),
MainActivity.dataBase.getDetailedTextForNews(MainActivity.existingForNews.get(myPosition)),
MainActivity.dataBase.getTitleForNews(MainActivity.existingForNews.get(myPosition)),
MainActivity.detailImageNews,
adaptersForGallery.get(myPosition)
,view2);
while (MainActivity.currentViewPosition != 1) {
MainActivity.mContainer.showNext();
Log.w("position", "" + MainActivity.currentViewPosition);
if (MainActivity.currentViewPosition > 2) {
MainActivity.currentViewPosition = 0;
}
MainActivity.currentViewPosition += 1;
}
}
});
break;
case 2:
if(convertView == null)
{
rowView = inflater.inflate(R.layout.newsvideocelladapter, parent, false);
}
else
{
rowView = convertView;
}
Uri uri=Uri.parse(videoUrls.get(position));
VideoView video = (VideoView) rowView.findViewById(R.id.newsVideo);
video.setVideoURI(uri);
break;
default:
if(convertView == null)
{
rowView = inflater.inflate(R.layout.newstextcelladapter, parent, false);
}
else
{
rowView = convertView;
}
break;
}
TextView titleView = (TextView) rowView.findViewById(R.id.newsTitleView);
TextView dateView = (TextView) rowView.findViewById(R.id.newsDateView);
TextView timeView = (TextView) rowView.findViewById(R.id.newsTimeView);
TextView commentsView = (TextView) rowView.findViewById(R.id.newsCommentView);
titleView.setText(this.title.get(position));
dateView.setText(this.date.get(position));
timeView.setText(this.time.get(position));
commentsView.setText(Integer.toString(this.comments.get(position)));
return rowView;
}
public View getView(int position, View convertView, ViewGroup parent) {
View i ;
ImageView iv;
ProgressBar mProgressBar;
calledGetView+=1;
Log.i("Image View:URL", ""+mImageIds.get(position));
if(convertView == null)
{
i = MainActivity.factory.inflate(R.layout.imagespinner, null);
}
else
{
i = (ImageView) convertView;
}
mProgressBar =(ProgressBar) i.findViewById(R.id.imageProgress);
iv = (ImageView) i.findViewById(R.id.image);
try {
AsycTask task = new AsycTask();
task.url = new URL(mImageIds.get(position));
task.iv = iv;
task.execute(iv);
iv.setAdjustViewBounds(true);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setLayoutParams(new RelativeLayout.LayoutParams((int) (MainActivity.screenWidth*0.7), (int) ((MainActivity.screenWidth*0.7)*0.6)));
task.globalPosition = currentPosition;
task.mProgressBar = mProgressBar;
if(task.bm == null)
{
}
}
catch (IOException e) {
Log.i("Asyc task", "FATAL ERROR");
e.printStackTrace();
}
return i;
}
public class AsycTask extends AsyncTask<ImageView, Void, Bitmap> {
public Bitmap bm;
public Bitmap bm2;
public int globalPosition;
public ProgressBar mProgressBar;
public int imagePosition;
public ImageView iv;
public URL url;
public Canvas c;
#Override
protected Bitmap doInBackground(ImageView... arg0) {
iv = arg0[0];
//Log.w("Loading url:",""+ url.getPath());
try {
bm2 = BitmapFactory.decodeStream((InputStream) url.getContent());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OutOfMemoryError e) {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inSampleSize = 2;
o.inDither = false;
o.inPurgeable = true;
try {
bm2 = BitmapFactory.decodeStream(
(InputStream) url.getContent(), null, o);
} catch (IOException e1) {
e1.printStackTrace();
} catch (OutOfMemoryError e1) {
}
}
return bm2;
}
private void updateView(int index){
View v = MainActivity.newsListView.getChildAt(index -
MainActivity.newsListView.getFirstVisiblePosition());
}
#Override
protected void onPostExecute(Bitmap result) {
mProgressBar.setVisibility(View.GONE);
iv.setVisibility(View.GONE);
iv.setVisibility(View.VISIBLE);
BitmapDrawable dr = ((BitmapDrawable) iv.getDrawable());
if (dr != null) {
Bitmap bmForRecyl = dr.getBitmap();
if (bmForRecyl != null) {
bmForRecyl.recycle();
}
}
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setImageBitmap(result);
Log.i("Set", "setted");
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
mProgressBar.incrementProgressBy(5);
}
}
I know for this problem but I dont know how to resolve it for listview with gallery with asyctask.
I think this is because the gallery is not loaded with the new adapter.How to change the adapter?
You need to override getViewItemType.
getViewTypeCount() - this methods returns information how many types of rows do you have in your list
getItemViewType(int position) - returns information which layout type you should use based on position
Then you inflate layout only if it's null and determine type using getItemViewType.
Example :
private static final int TYPE_ITEM1 = 0;
private static final int TYPE_ITEM2 = 1;
private static final int TYPE_ITEM3 = 2;
#Override
public int getItemViewType(int position)
{
int type;
if (position== 0){ // your condition
type = TYPE_ITEM1; //type 0 for image
} else if(position == 1){
type = TYPE_ITEM2; //type 1 for text
}else {
type = TYPE_ITEM3; //type 2 for videos
}
return type;
}
#Override
public int getViewTypeCount() {
return 3; //three different layouts to be inflated
}
In getView
int type= getItemViewType(arg0);
switch (type) {
case TYPE_ITEM1:
// inflate layout for text
break;
case TYPE_ITEM2:
// inflate layout for image
break;
case TYPE_ITEM3:
// inflate layout for video
break;
....
You can check the tutorial below
http://android.amberfog.com/?p=296
I am looking to build something similar to the settings UI of system android. I want something like a few checkboxpreferences, switchpreferences, edittextpreferences on the launch of application and then when user selects one preference open a fragment but i am just not able to figure that out.
I have referred Settings guide but it insists on using preference header. While displaying headers there is an unlikely overhead i am facing of displaying texts which in turn will load fragments.
For example,
My preference header is something like :
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- These settings headers are only used on tablets. -->
<header
android:fragment="${packageName}.${activityClass}$GeneralPreferenceFragment"
android:title="#string/pref_header_general" />
<header
android:fragment="${packageName}.${activityClass}$NotificationPreferenceFragment"
android:title="#string/pref_header_notifications" />
<header
android:fragment="${packageName}.${activityClass}$DataSyncPreferenceFragment"
android:title="#string/pref_header_data_sync" />
</preference-headers>
and just to load the actual data, i am having to use it. The actual data will have checkboxes and edittexts.
It would be great if someone gave some insights on this. It would be of great help if i could launch the actual fragment data on loading of screen. Better if i could have control of what fragment to call and call other fragments when a fragment item is selected.
To create custom preference headers, with switches and such, you need to extend PreferenceActivity with Headers as the Android docs describe and then override PreferenceActivity.setListAdapter to create your own list adapter, which creates the custom views. I made a pastebin with the code from the actual android settings activity to help you out. http://pastebin.com/RhSndGCQ
#Override
public void onBuildHeaders(List<Header> headers) {
loadHeadersFromResource(R.xml.settings_headers, headers);
updateHeaderList(headers);
}
#Override
public void setListAdapter(ListAdapter adapter) {
if (adapter == null) {
super.setListAdapter(null);
} else {
super.setListAdapter(new HeaderAdapter(this, getHeaders(), mAuthenticatorHelper));
}
}
private static class HeaderAdapter extends ArrayAdapter<Header> {
static final int HEADER_TYPE_CATEGORY = 0;
static final int HEADER_TYPE_NORMAL = 1;
static final int HEADER_TYPE_SWITCH = 2;
private static final int HEADER_TYPE_COUNT = HEADER_TYPE_SWITCH + 1;
private final WifiEnabler mWifiEnabler;
private final BluetoothEnabler mBluetoothEnabler;
private final ProfileEnabler mProfileEnabler;
private AuthenticatorHelper mAuthHelper;
private static class HeaderViewHolder {
ImageView icon;
TextView title;
TextView summary;
Switch switch_;
}
private LayoutInflater mInflater;
static int getHeaderType(Header header) {
if (header.fragment == null && header.intent == null) {
return HEADER_TYPE_CATEGORY;
} else if (header.id == R.id.wifi_settings
|| header.id == R.id.bluetooth_settings
|| header.id == R.id.profiles_settings) {
return HEADER_TYPE_SWITCH;
} else {
return HEADER_TYPE_NORMAL;
}
}
#Override
public int getItemViewType(int position) {
Header header = getItem(position);
return getHeaderType(header);
}
#Override
public boolean areAllItemsEnabled() {
return false; // because of categories
}
#Override
public boolean isEnabled(int position) {
return getItemViewType(position) != HEADER_TYPE_CATEGORY;
}
#Override
public int getViewTypeCount() {
return HEADER_TYPE_COUNT;
}
#Override
public boolean hasStableIds() {
return true;
}
public HeaderAdapter(Context context, List<Header> objects,
AuthenticatorHelper authenticatorHelper) {
super(context, 0, objects);
mAuthHelper = authenticatorHelper;
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Temp Switches provided as placeholder until the adapter replaces these with actual
// Switches inflated from their layouts. Must be done before adapter is set in super
mWifiEnabler = new WifiEnabler(context, new Switch(context));
mBluetoothEnabler = new BluetoothEnabler(context, new Switch(context));
mProfileEnabler = new ProfileEnabler(context, null, new Switch(context));
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
Header header = getItem(position);
int headerType = getHeaderType(header);
View view = null;
if (convertView == null || headerType == HEADER_TYPE_SWITCH) {
holder = new HeaderViewHolder();
switch (headerType) {
case HEADER_TYPE_CATEGORY:
view = new TextView(getContext(), null,
android.R.attr.listSeparatorTextViewStyle);
holder.title = (TextView) view;
break;
case HEADER_TYPE_SWITCH:
view = mInflater.inflate(R.layout.preference_header_switch_item, parent,
false);
holder.icon = (ImageView) view.findViewById(R.id.icon);
holder.title = (TextView)
view.findViewById(com.android.internal.R.id.title);
holder.summary = (TextView)
view.findViewById(com.android.internal.R.id.summary);
holder.switch_ = (Switch) view.findViewById(R.id.switchWidget);
break;
case HEADER_TYPE_NORMAL:
view = mInflater.inflate(
R.layout.preference_header_item, parent,
false);
holder.icon = (ImageView) view.findViewById(R.id.icon);
holder.title = (TextView)
view.findViewById(com.android.internal.R.id.title);
holder.summary = (TextView)
view.findViewById(com.android.internal.R.id.summary);
break;
}
view.setTag(holder);
} else {
view = convertView;
holder = (HeaderViewHolder) view.getTag();
}
// All view fields must be updated every time, because the view may be recycled
switch (headerType) {
case HEADER_TYPE_CATEGORY:
holder.title.setText(header.getTitle(getContext().getResources()));
break;
case HEADER_TYPE_SWITCH:
// Would need a different treatment if the main menu had more switches
if (header.id == R.id.wifi_settings) {
mWifiEnabler.setSwitch(holder.switch_);
} else if (header.id == R.id.bluetooth_settings) {
mBluetoothEnabler.setSwitch(holder.switch_);
} else if (header.id == R.id.profiles_settings) {
mProfileEnabler.setSwitch(holder.switch_);
}
// No break, fall through on purpose to update common fields
//$FALL-THROUGH$
case HEADER_TYPE_NORMAL:
if (header.extras != null
&& header.extras.containsKey(ManageAccountsSettings.KEY_ACCOUNT_TYPE)) {
String accType = header.extras.getString(
ManageAccountsSettings.KEY_ACCOUNT_TYPE);
ViewGroup.LayoutParams lp = holder.icon.getLayoutParams();
lp.width = getContext().getResources().getDimensionPixelSize(
R.dimen.header_icon_width);
lp.height = lp.width;
holder.icon.setLayoutParams(lp);
Drawable icon = mAuthHelper.getDrawableForType(getContext(), accType);
holder.icon.setImageDrawable(icon);
} else {
holder.icon.setImageResource(header.iconRes);
}
holder.title.setText(header.getTitle(getContext().getResources()));
CharSequence summary = header.getSummary(getContext().getResources());
if (!TextUtils.isEmpty(summary)) {
holder.summary.setVisibility(View.VISIBLE);
holder.summary.setText(summary);
} else {
holder.summary.setVisibility(View.GONE);
}
break;
}
return view;
}
public void resume() {
mWifiEnabler.resume();
mBluetoothEnabler.resume();
mProfileEnabler.resume();
}
public void pause() {
mWifiEnabler.pause();
mBluetoothEnabler.pause();
mProfileEnabler.pause();
}
}