I have a custom adapter added to listview. Data is call logs from phone. I reduce list by show only records from 3 days. Problem is that when I try to scroll listview from top to bottom I have a huge lags. My Scroll isn't smooth. Is there any way to make listview scroll smoother?
Here is my custom adapter:
public class CallListAdapter extends ArrayAdapter<CallList> {
Activity activity;
public CallListAdapter(Context context, ArrayList<CallList> calls, Activity activity) {
super(context, 0, calls);
this.activity = activity;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final CallList callList = getItem(position);
int actualPosition = 0;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.call_list, parent, false);
}
final TextView call1 = convertView.findViewById(R.id.callNumber);
final TextView call2 = convertView.findViewById(R.id.callDate);
final TextView call3 = convertView.findViewById(R.id.conversationTime);
final TextView call4 = convertView.findViewById(R.id.callType);
final Button callView = convertView.findViewById(R.id.getViewName);
final ImageView bio = convertView.findViewById(R.id.lookBio);
final ImageView edit = convertView.findViewById(R.id.edit_call);
final ImageView block = convertView.findViewById(R.id.blockCall);
final ImageView call = convertView.findViewById(R.id.callUser);
final TextView bioLabel = convertView.findViewById(R.id.BioLabelSug);
final TextView editLabel = convertView.findViewById(R.id.NoteLabel);
final TextView blockLabel = convertView.findViewById(R.id.BlockLabelSug);
final TextView callLabel = convertView.findViewById(R.id.CallLabelSug);
final ConstraintLayout callContainer = convertView.findViewById(R.id.contact_container);
final ConstraintLayout bioContainer = convertView.findViewById(R.id.bio_container);
final ConstraintLayout blockContainer = convertView.findViewById(R.id.ignore_container);
final ConstraintLayout noteContainer = convertView.findViewById(R.id.note_container);
final TextView btnMarg = convertView.findViewById(R.id.buttonMargin);
final TextView callListNr2 = convertView.findViewById(R.id.callNumber2);
final LayoutInflater factory = activity.getLayoutInflater();
final View fullView = factory.inflate(R.layout.fragment_calls, null);
final RelativeLayout loading = fullView.findViewById(R.id.loadingBar);
String[] jsonData = new manageCalls().intentCallValues(position);
StringBuilder builder = new StringBuilder();
for (String s : jsonData) {
builder.append(s + "\n");
}
String str = builder.toString();
final String num = jsonData[0];
final String dat = jsonData[1];
final String typeCall = jsonData[2];
final String dur = jsonData[3];
final String authToken = SaveSharedPreferences.getPrefTokenName(getContext());
final Animation slideUp = AnimationUtils.loadAnimation(getContext(), R.anim.slideup);
final Animation slideDown = AnimationUtils.loadAnimation(getContext(), R.anim.slidedown);
final Handler handler = new Handler();
callView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (bioContainer.getVisibility() == View.GONE) {
callListNr2.setVisibility(View.GONE);
bio.setVisibility(View.VISIBLE);
bioLabel.setVisibility(View.VISIBLE);
edit.setVisibility(View.VISIBLE);
editLabel.setVisibility(View.VISIBLE);
} else if (bioContainer.getVisibility() == View.VISIBLE) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
bio.setVisibility(View.GONE);
callContainer.setVisibility(View.GONE);
bioContainer.setVisibility(View.GONE);
noteContainer.setVisibility(View.GONE);
blockContainer.setVisibility(View.GONE);
}
}, 300);
}
}
});
if (actualPosition != position) {
if (bioContainer.getVisibility() == View.VISIBLE) {
bioContainer.setVisibility(View.GONE);
callContainer.setVisibility(View.GONE);
noteContainer.setVisibility(View.GONE);
blockContainer.setVisibility(View.GONE);
}
actualPosition = position;
}
call.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
call.setEnabled(false);
loading.setVisibility(View.VISIBLE);
Intent intentCall = new Intent(view.getContext(), CallUserActivity.class);
intentCall.putExtra("number", num);
intentCall.putExtra("authToken", authToken);
intentCall.putExtra("Date", dat);
activity.startActivityForResult(intentCall, position);
handler.postDelayed(new Runnable() {
#Override
public void run() {
call.setEnabled(true);
loading.setVisibility(View.GONE);
}
}, 1000);
}
});
call2.setText(callList.callDate);
call3.setText(callList.conversationTime);
call4.setText(callList.callType);
return convertView;
}
}
Try use ViewHolder and use AsyncTask to load bitmap.
You can try this way.
private static class ViewHolder {
public TextView call1;
public TextView call2;
public TextView call3;
public TextView call4;
public Button callView;
public ImageView bio;
public ImageView edit;
public ImageView block;
public ImageView call;
public TextView bioLabel;
public TextView editLabel;
public TextView blockLabel;
public TextView callLabel;
public ConstraintLayout callContainer;
public ConstraintLayout bioContainer;
public ConstraintLayout blockContainer;
public ConstraintLayout noteContainer;
public TextView btnMarg;
public TextView callListNr2;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
// inflate the layout
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.call1 = convertView.findViewById(R.id....);
holder.call2 = convertView.findViewById(R.id....);
//Same for all other views
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.call1.setText(....);
//Lazy load for bitmap
loadBitmap(yourFileName..., bio)
return convertView;
}
static class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
#Override
protected Bitmap doInBackground(String... params) {
return decodeSampledBitmapFromResource(params[0], 300, 300);
}
// Once complete, see if ImageView is still around and set bitmap.
#Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
public void loadBitmap(String fileName, ImageView imageView) {
BitmapWorkerTask task = new BitmapWorkerTask(imageView);
task.execute(fileName);
}
public static Bitmap decodeSampledBitmapFromResource(String fileName,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(fileName, options);
}
Your getview is HUGE.
Your (if convertview==null) has basically almost no effect as you're setting up the view again anyways.
What you need to do is refactor the getview to not be so slow. one thing you can do is create a class that has all the findviews done already for you and put that then in the .tag of the converted view. change your onclicks to use that as well, in a manner where you don't have to recreate them(other ways to do that exist as well).
ideally your code for if you have a converted view already should be just the .settexts().
depending on the size of your list, you could just get away with creating a view for each callist and avoid recycling the converted views alltogether, in such case you could just create them in advance.
also depending on the size of your list you could just get away with creating a just a simple linearlayout instead inside a scrollview. if your list isn't huge and it's not for some old phones, it works just fine as well (Don't knock on this as bad advice until you try on your phone how huge it can be before a listview starts making more sense).
I have implemented a ViewHolderAdapter to load items and display it on a ListView, but I want to display also a AdMob Banner in some rows. I have created a custom Adapter for two different Layouts. But the problem is that only display two rows, one for each Layout, when the item list is longer than 400 items.
Somebody can help me?
I show the code below:
[![enter image description here][1]][1]public class SubliguesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static List<Subligues> items;
public static class ClasGeneralViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
// Campos respectivos de un item
public TextView subligue_name;
public TextView created_at;
public TextView members;
public ImageView icon;
public ClasGeneralViewHolder(View v) {
super(v);
subligue_name = (TextView) v.findViewById(R.id.txt_subligue_name);
created_at = (TextView) v.findViewById(R.id.txt_created_at);
members = (TextView) v.findViewById(R.id.txt_members);
icon = (ImageView) v.findViewById(R.id.imageViewIcon);
v.setOnClickListener(this);
}
public void onClick(View view){
String subligue_name= items.get(getPosition()).getSubligueName();
// Launch RegisterUser
Intent intent = new Intent(view.getContext(),
RegisterUser.class);
// Pasar el nombre de la liga del usuario a RegisterUser.java
intent.putExtra("subligue_name",subligue_name);
view.getContext().startActivity(intent);
((Activity) view.getContext()).finish();
}
}
public static class BannerViewHolder extends RecyclerView.ViewHolder{
// Admob banner
public AdView mAdView;
public BannerViewHolder(View v) {
super(v);
mAdView = (AdView) v.findViewById(R.id.adView);
}
}
#Override
public int getItemViewType(int position) {
// here your custom logic to choose the view type
return position %10;
}
public SubliguesAdapter(List<Subligues> items) {
this.items = items;
}
#Override
public int getItemCount() {
return items.size();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
switch (i) {
case 0:
View v2 = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_banner, viewGroup, false);
return new BannerViewHolder(v2); // view holder for banner items;
case 1:
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.activity_register_existente_abierta_card, viewGroup, false);
return new ClasGeneralViewHolder(v); // view holder for normal items;
}
return null;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int i) {
switch (viewHolder.getItemViewType()) {
case 0:
BannerViewHolder viewHolder2 = (BannerViewHolder)viewHolder;
AdRequest adRequest = new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).build();
viewHolder2.mAdView.loadAd(adRequest);
break;
case 1:
ClasGeneralViewHolder viewHolder0 = (ClasGeneralViewHolder)viewHolder;
viewHolder0.subligue_name.setText(String.valueOf(items.get(i).getSubligueName()));
String created_at = items.get(i).getCreatedAt().substring(0, items.get(i).getCreatedAt().length() - 9);
viewHolder0.created_at.setText(created_at);
viewHolder0.members.setText(String.valueOf(items.get(i).getMembers())+" ");
new ImageDownloaderTask(viewHolder0.icon).execute(items.get(i).getIcon());
break;
}
}
class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public ImageDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
#Override
protected Bitmap doInBackground(String... params) {
return downloadBitmap(params[0]);
}
#Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
Drawable placeholder = imageView.getContext().getResources().getDrawable(R.drawable.no_team);
imageView.setImageDrawable(placeholder);
}
}
}
}
}
private Bitmap downloadBitmap(String url) {
HttpURLConnection urlConnection = null;
try {
URL uri = new URL(url);
urlConnection = (HttpURLConnection) uri.openConnection();
int statusCode = urlConnection.getResponseCode();
if (statusCode != HttpStatus.SC_OK) {
return null;
}
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
} catch (Exception e) {
urlConnection.disconnect();
Log.w("ImageDownloader", "Error downloading image from " + url);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null;
}
}
#Override
public int getItemViewType(int position) {
// here your custom logic to choose the view type
return position %2;
}
I haven't run ur code but clearly this part is responsible for displaying different views in alternative viewholders, because you are taking modulus by 2, which will return you 0 for even numbers and 1 for odd numbers.
Do two things
return position % 10 will increase interval for ads you can give
any number after which u want to put ad.
Also to make it work perfectly with this logic change case 0 to adview and 1 to otherview.
This will resolve your problem.
I am getting a memory leak from the following code. It is an activity that contains a mainViewPager. That viewPager return 4 different fragments, which each have their own ViewPagers that hold images which are being retrieved from the same asyncTask. Here is my code. When I run it I can scroll throught the Pages with some lag. But when I exit the go back into the activity I get an Out Of Memory Error. So it must be a memory leak. I've stared at my code forever and I can't figure out why. Please help me... PS. I am using the Picasso library to fetch the images from a server.
Activity
package info.nightowl.nightowl;
import info.nightowl.nightowl.LocationsGridFragment.onLocationSelectedListener;
public class NightWatch extends FragmentActivity implements onLocationSelectedListener {
public static ArrayList<String> imageUrl = new ArrayList<String>();
public static ArrayList<String> dateList = new ArrayList<String>();
public static ArrayList<String> trendList = new ArrayList<String>();
public static ArrayList<String> nameList = new ArrayList<String>();
public static ArrayList<String> imageLocationsList = new ArrayList<String>();
public static ArrayList<String> imageClubsList = new ArrayList<String>();
public static ArrayList<String> locationsList = new ArrayList<String>();
public static ArrayList<String> clubsList = new ArrayList<String>();
public static ArrayList<String> locationImagesUrl = new ArrayList<String>();
public static ArrayList<String> addressList = new ArrayList<String>();
public static ArrayList<String> hotImageUrl = new ArrayList<String>();
public static ArrayList<String> hotDateList = new ArrayList<String>();
public static ArrayList<String> hotTrendList = new ArrayList<String>();
public static ArrayList<String> hotNameList = new ArrayList<String>();
public static ArrayList<String> hotImageLocationsList = new ArrayList<String>();
public static ArrayList<String> hotImageClubsList = new ArrayList<String>();
FetchClubs fetchClubs = null;
public int width, height;
public JSONArray list;
public final String IMAGE_URL = "http://www.night-owl.info/webservice/";
SharedPreferences prefs;
static FeedFragment feedFragment;
static LocationsFragment locationsFragment;
static HotFragment hotFragment;
static ClubsFragment clubsFragment;
CustomViewPager customPager;
CustomViewPageAdapter theAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_night_watch);
//Method to set up the tabs
getSizes();
setupFragments();
updateList();
prefs = getSharedPreferences("prefs", 0);
}
//Called from the fragment which fetches image
public void loadBitmap(String image, ImageView imageView, boolean grid, TextView loadText) {
int size;
if (grid) size = (width-width/9)/3;
else size = width - width/9;
Log.d("Pager About to load", "Pager Loading bitmap picasso");
getBitmap load = new getBitmap(image, imageView, size, loadText);
load.execute(image);
}
public class getBitmap extends AsyncTask<String, Void, Bitmap> {
String loadImageUrl;
Bitmap bmp;
int sizes;
TextView loadingTextView;
private final WeakReference<ImageView> imageViewReference;
public getBitmap(String image, ImageView imageView, int size, TextView loadText){
imageViewReference = new WeakReference<ImageView>(imageView);
sizes = size;
loadingTextView = loadText;
}
#Override
protected void onPreExecute() {
Log.d("async", "async starting");
super.onPreExecute();
}
#Override
protected Bitmap doInBackground(String... arg0) {
// TODO Auto-generated method stub
try {
bmp = Picasso.with(NightWatch.this).load(IMAGE_URL+arg0[0]).resize(sizes,
sizes).get();
} catch (IOException e) {
Log.d("ioexc", "Pager IOEXCEPTION IDIOT!!!");
e.printStackTrace();
}
return bmp;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
/*RoundedCornersDrawable drawable = new RoundedCornersDrawable(getResources(), bmp);
loadImage.setImageDrawable(drawable);
loadingTextView.setVisibility(View.GONE);
loadImage.setVisibility(View.VISIBLE);*/
if(imageViewReference != null && bitmap!= null) {
final ImageView imageView = imageViewReference.get();
if(imageView != null) {
imageView.setImageBitmap(bitmap);
loadingTextView.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
}
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.feed, menu);
return true;
}
//SET UP THE TWO TABS 'FEED' AND 'LOCATIONS'
//Update ArrayList of the image names
public void updateList() {
imageUrl.clear();
trendList.clear();
dateList.clear();
nameList.clear();
imageLocationsList.clear();
imageClubsList.clear();
locationsList.clear();
clubsList.clear();
locationImagesUrl.clear();
addressList.clear();
hotImageUrl.clear();
hotTrendList.clear();
hotDateList.clear();
hotNameList.clear();
hotImageLocationsList.clear();
hotImageClubsList.clear();
new getImageUrl().execute();
new getLocationsUrl().execute();
}
class getImageUrl extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... arg0) {
JSONParser parser = new JSONParser();
JSONObject json = parser.getJSONFromUrl(IMAGE_URL + "updateimages.php");
try {
list = json.getJSONArray("posts");
for(int i = 0; i < list.length(); i++) {
JSONObject c = list.getJSONObject(i);
String imgSrc = c.getString("source");
String trend = c.getString("trend");
String date = c.getString("date");
String name = c.getString("name");
String location = c.getString("location");
String club = c.getString("club");
imageUrl.add(imgSrc);
dateList.add(date);
trendList.add(trend);
nameList.add(name);
imageLocationsList.add(location);
imageClubsList.add(club);
Log.d("async trend", trendList.get(0));
}
Log.d("Got list", imageUrl.get(0) + " " + trendList.get(0));
} catch(JSONException je) {
je.printStackTrace();
}
try {
list = json.getJSONArray("hot");
for(int i = 0; i < list.length(); i++) {
JSONObject c = list.getJSONObject(i);
String imgSrc = c.getString("source");
String trend = c.getString("trend");
String date = c.getString("date");
String name = c.getString("name");
String location = c.getString("location");
String club = c.getString("club");
hotImageUrl.add(imgSrc);
hotDateList.add(date);
hotTrendList.add(trend);
hotNameList.add(name);
hotImageLocationsList.add(location);
hotImageClubsList.add(club);
Log.d("async trend", trendList.get(0));
}
Log.d("Got list","hot list" + hotImageUrl.get(0) + " " + hotTrendList.get(0));
} catch(JSONException je) {
je.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
hotFragment.updateAdapter();
feedFragment.updateAdapter();
}
}
public void scrollMainPager(int pos) {
customPager.setCurrentItem(pos, true);
}
public void scrollPager(int pos) {
feedFragment.scrollPager(pos);
}
public void setupFragments() {
feedFragment = new FeedFragment();
locationsFragment = new LocationsFragment();
hotFragment = new HotFragment();
clubsFragment = new ClubsFragment();
customPager = (CustomViewPager) findViewById(R.id.customviewpager);
customPager.setOffscreenPageLimit(3);
theAdapter = new CustomViewPageAdapter(getSupportFragmentManager());
customPager.setAdapter(theAdapter);
customPager.setCurrentItem(1);
}
//GET SIZES OF SCREEN
public void getSizes(){
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}
public static class CustomViewPageAdapter extends FragmentStatePagerAdapter {
public CustomViewPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
if(arg0 == 0) return hotFragment;
else if(arg0 == 1) return feedFragment;
else if(arg0 == 2) return locationsFragment;
else if(arg0 == 3) return clubsFragment;
return null;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return 4;
}
}
#Override
public void onLocationSelected(int position) {
}
}
FeedFragment
public class FeedFragment extends Fragment implements OnClickListener {
ToggleButton buttonGrid;
static Spinner spinnerUploadStatus;
CustomEditText et;
CustomScrollTextView tv;
int width, height;
View view;
static boolean isGrid;
ViewPager mPager;
SharedPreferences prefs;
public ImagePagerAdapter mPageAdapter;
Button buttonSwitchFragment;
Integer[] b = { R.drawable.statusunpressed, R.drawable.red,
R.drawable.green, R.drawable.blue };
List<Integer> spinnerList = new ArrayList<Integer>(Arrays.asList(b));
CustomSpinnerAdapter myAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
prefs = getActivity().getSharedPreferences("prefs", 0);
getSizes();
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.activity_feed, container, false);
setup();
return view;
}
#SuppressLint("NewApi")
public void setup() {
isGrid = false;
mPager = (ViewPager) view.findViewById(R.id.myviewpager1);
mPager.setOffscreenPageLimit(0);
buttonGrid = (ToggleButton) view.findViewById(R.id.button_grid);
buttonGrid.setOnClickListener(this);
spinnerUploadStatus = (Spinner) view
.findViewById(R.id.buttonUploadStatus);
myAdapter = new CustomSpinnerAdapter(getActivity(),
R.layout.item_simple_list_item, spinnerList);
myAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerUploadStatus.setAdapter(myAdapter);
spinnerUploadStatus.setDropDownWidth((int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()));
spinnerUploadStatus.setOnItemSelectedListener(myOnItemSelectedListener);
spinnerUploadStatus.getBackground().setAlpha(0);
buttonSwitchFragment = (Button) view
.findViewById(R.id.buttonSwitchFragment);
buttonSwitchFragment.setOnClickListener(this);
Typeface font = Typeface.createFromAsset(getActivity().getAssets(),
"NotCourierSans.ttf");
et = (CustomEditText) view.findViewById(R.id.customEditText1);
et.updateTypeFace(font);
tv = (CustomScrollTextView) view
.findViewById(R.id.customscrolltextview);
tv.setText("WELCOME TO NIGHTOWL");
tv.setTypeface(font);
tv.start(width / 2500.0);
Log.d("width", "width is " + width);
}
public void getSizes() {
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_grid:
isGrid = !isGrid;
updateAdapter();
break;
case R.id.buttonSwitchFragment:
((NightWatch) getActivity()).scrollMainPager(2);
break;
}
}
public OnItemSelectedListener myOnItemSelectedListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
int colour = arg2;
spinnerUploadStatus.setSelection(0, true);
et.sendText(prefs.getString("username", "username invalid"), colour);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
};
public void scrollPager(int position) {
isGrid = false;
buttonGrid.setChecked(false);
updateAdapter();
mPager.setCurrentItem(position, true);
Log.d("Pager", "PAGER UPDATED");
}
public static void disableButton(Boolean enabled) {
spinnerUploadStatus.setEnabled(enabled);
}
public void updateAdapter() {
int theSize;
if (!isGrid)
theSize = NightWatch.imageUrl.size();
else if (NightWatch.imageUrl.size() % 9 > 0)
theSize = NightWatch.imageUrl.size() / 9 + 1;
else
theSize = NightWatch.imageUrl.size() / 9;
mPageAdapter = new ImagePagerAdapter(getChildFragmentManager(), theSize);
mPager.setAdapter(mPageAdapter);
Log.d("size of viewPager Adapter", "" + theSize);
}
public static class ImagePagerAdapter extends FragmentStatePagerAdapter {
int mSize;
public ImagePagerAdapter(FragmentManager fm, int size) {
super(fm);
mSize = size;
}
#Override
public Fragment getItem(int arg0) {
// TODO Auto-generated method stub
Log.d("Starting imageDetailFragment", "");
Log.d("Pager", "Pager starting fragment");
Log.d("GRID", "fuck grid");
if (!isGrid)
return ImageDetailFragment.newInstance(
arg0, NightWatch.imageUrl, NightWatch.nameList,
NightWatch.trendList, NightWatch.dateList);
else
return GridFragment.newInstance(arg0, NightWatch.imageUrl);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return mSize;
}
}
public class CustomSpinnerAdapter extends ArrayAdapter<Integer> {
List<Integer> resourceId;
Context c;
public CustomSpinnerAdapter(Context context, int textViewResourceId,
List<Integer> objects) {
super(context, textViewResourceId, objects);
resourceId = objects;
c = context;
}
#Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
return getCustomDropdownView(position, convertView, parent);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}
public View getCustomView(int position, View convertView,
ViewGroup parent) {
ImageView imageView = new ImageView(c);
imageView.setImageResource(resourceId.get(position));
imageView.setLayoutParams(new ListView.LayoutParams(
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()), (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 34,
getResources().getDisplayMetrics())));
return imageView;
}
public View getCustomDropdownView(int position, View convertView,
ViewGroup parent) {
ImageView imageView = new ImageView(c);
imageView.setImageResource(resourceId.get(position));
imageView.setLayoutParams(new ListView.LayoutParams(
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()), (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 34,
getResources().getDisplayMetrics())));
if (position == 0) {
imageView.setVisibility(View.GONE);
}
return imageView;
}
}
}
ImageDetailFragment
package info.nightowl.nightowl;
import java.io.IOException;
import java.util.ArrayList;
import com.example.nightowl.R;
import com.squareup.picasso.Picasso;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class ImageDetailFragment extends Fragment implements OnClickListener {
int mImageNum;
ImageView imageView;
TextView trendTextView;
TextView nameTextView;
TextView dateTextView;
TextView loadingTextView;
Button upVoteButton, downVoteButton;
final String list = "voteList";
static SharedPreferences prefs;
SharedPreferences.Editor editor;
public ArrayList<String> imageUrl;
public ArrayList<String> trendList;
public ArrayList<String> nameList;
public ArrayList<String> dateList;
RelativeLayout.LayoutParams rParams;
int width, height;
static ImageDetailFragment newInstance(int imageNum,
ArrayList<String> imageList, ArrayList<String> tempNameList,
ArrayList<String> tempTrendList, ArrayList<String> tempDateList) {
final ImageDetailFragment f = new ImageDetailFragment();
Bundle args = new Bundle();
args.putInt("imageNum", imageNum);
args.putStringArrayList("imageList", imageList);
args.putStringArrayList("nameList", tempNameList);
args.putStringArrayList("trendList", tempTrendList);
args.putStringArrayList("dateList", tempDateList);
f.setArguments(args);
return f;
}
public ImageDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mImageNum = getArguments().getInt("imageNum");
imageUrl = getArguments().getStringArrayList("imageList");
nameList = getArguments().getStringArrayList("nameList");
trendList = getArguments().getStringArrayList("trendList");
dateList = getArguments().getStringArrayList("dateList");
} else
mImageNum = -1;
prefs = getActivity().getSharedPreferences("prefs", 0);
editor = getActivity().getSharedPreferences("prefs", 0).edit();
getSizes();
rParams = new RelativeLayout.LayoutParams((width - width/9), width - width/9);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.image_detail_fragment,
container, false);
imageView = (ImageView) v.findViewById(R.id.imageView1);
imageView.setVisibility(View.INVISIBLE);
loadingTextView = (TextView) v.findViewById(R.id.loadingTextView);
loadingTextView.setVisibility(View.VISIBLE);
trendTextView = (TextView) v.findViewById(R.id.trendTextView);
nameTextView = (TextView) v.findViewById(R.id.nameTextView);
dateTextView = (TextView) v.findViewById(R.id.dateTextView);
upVoteButton = (Button) v.findViewById(R.id.buttonUpVote);
downVoteButton = (Button) v.findViewById(R.id.buttonDownVote);
rParams.addRule(RelativeLayout.BELOW, nameTextView.getId());
rParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
imageView.setLayoutParams(rParams);
upVoteButton.setOnClickListener(this);
downVoteButton.setOnClickListener(this);
if (NightWatch.class.isInstance(getActivity())) {
Typeface font = Typeface.createFromAsset(getActivity().getAssets(),
"NotCourierSans.ttf");
final String image = imageUrl.get(mImageNum);
((NightWatch) getActivity()).loadBitmap(image, imageView, false, loadingTextView);
trendTextView.setText(trendList.get(mImageNum));
nameTextView.setText(nameList.get(mImageNum));
dateTextView.setText(dateList.get(mImageNum));
updateButtonBackgrounds();
loadingTextView.setTypeface(font);
trendTextView.setTypeface(font);
nameTextView.setTypeface(font);
dateTextView.setTypeface(font);
Log.d("fragment trend", NightWatch.trendList.get(0));
}
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonUpVote:
if (prefs.getInt(imageUrl.get(mImageNum), 0) == -1) {
downVoteButton
.setBackgroundResource(R.drawable.downvoteunpressed);
upVoteButton.setBackgroundResource(R.drawable.upvotepressed);
((NightWatch) getActivity()).sendVote(1,
imageUrl.get(mImageNum));
} else if (prefs.getInt(imageUrl.get(mImageNum), 0) == 0) {
upVoteButton.setBackgroundResource(R.drawable.upvotepressed);
((NightWatch) getActivity()).sendVote(1,
imageUrl.get(mImageNum));
}
break;
case R.id.buttonDownVote:
if (prefs.getInt(imageUrl.get(mImageNum), 0) == 1) {
downVoteButton
.setBackgroundResource(R.drawable.downvotepressed);
upVoteButton.setBackgroundResource(R.drawable.upvoteunpressed);
((NightWatch) getActivity()).sendVote(-1,
imageUrl.get(mImageNum));
} else if (prefs.getInt(imageUrl.get(mImageNum), 0) == 0) {
downVoteButton
.setBackgroundResource(R.drawable.downvotepressed);
((NightWatch) getActivity()).sendVote(-1,
imageUrl.get(mImageNum));
}
break;
}
};
public void updateButtonBackgrounds() {
if (prefs.getInt(imageUrl.get(mImageNum), 0) == -1) {
downVoteButton.setBackgroundResource(R.drawable.downvotepressed);
} else if (prefs.getInt(imageUrl.get(mImageNum), 0) == 1) {
upVoteButton.setBackgroundResource(R.drawable.upvotepressed);
}
}
public static void sendVote(int vote, String imageName) {
prefs.edit().putInt(imageName, vote).commit();
}
public void getSizes() {
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}
}
HotFragment
package info.nightowl.nightowl;
public class HotFragment extends Fragment implements OnClickListener {
ToggleButton buttonGrid;
static Spinner spinnerUploadStatus;
CustomEditText et;
CustomScrollTextView tv;
int width, height;
View view;
static boolean isGrid;
ViewPager mPager;
SharedPreferences prefs;
public ImagePagerAdapter mPageAdapter;
Button buttonSwitchFragment;
Integer[] b = { R.drawable.statusunpressed, R.drawable.red,
R.drawable.green, R.drawable.blue };
List<Integer> spinnerList = new ArrayList<Integer>(Arrays.asList(b));
CustomSpinnerAdapter myAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
prefs = getActivity().getSharedPreferences("prefs", 0);
getSizes();
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.activity_feed, container, false);
setup();
return view;
}
#SuppressLint("NewApi")
public void setup() {
isGrid = false;
mPager = (ViewPager) view.findViewById(R.id.myviewpager1);
mPager.setOffscreenPageLimit(0);
buttonGrid = (ToggleButton) view.findViewById(R.id.button_grid);
buttonGrid.setOnClickListener(this);
spinnerUploadStatus = (Spinner) view
.findViewById(R.id.buttonUploadStatus);
myAdapter = new CustomSpinnerAdapter(getActivity(),
R.layout.item_simple_list_item, spinnerList);
myAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerUploadStatus.setAdapter(myAdapter);
spinnerUploadStatus.setDropDownWidth((int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()));
spinnerUploadStatus.setOnItemSelectedListener(myOnItemSelectedListener);
spinnerUploadStatus.getBackground().setAlpha(0);
buttonSwitchFragment = (Button) view
.findViewById(R.id.buttonSwitchFragment);
buttonSwitchFragment.setOnClickListener(this);
Typeface font = Typeface.createFromAsset(getActivity().getAssets(),
"NotCourierSans.ttf");
et = (CustomEditText) view.findViewById(R.id.customEditText1);
et.updateTypeFace(font);
tv = (CustomScrollTextView) view
.findViewById(R.id.customscrolltextview);
tv.setText("WELCOME TO NIGHTOWL");
tv.setTypeface(font);
tv.start(width / 2500.0);
Log.d("width", "width is " + width);
}
public void getSizes() {
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_grid:
isGrid = !isGrid;
updateAdapter();
break;
case R.id.buttonSwitchFragment:
((NightWatch) getActivity()).scrollMainPager(1);
break;
}
}
public OnItemSelectedListener myOnItemSelectedListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
spinnerUploadStatus.setSelection(0, true);
et.sendText(prefs.getString("username", "username invalid"), arg2);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
};
public void scrollPager(int position) {
isGrid = false;
buttonGrid.setChecked(false);
updateAdapter();
mPager.setCurrentItem(position, true);
Log.d("Pager", "PAGER UPDATED");
}
public static void disableButton(Boolean enabled) {
spinnerUploadStatus.setEnabled(enabled);
}
public void updateAdapter() {
int theSize;
if (!isGrid)
theSize = NightWatch.imageUrl.size();
else if (NightWatch.imageUrl.size() % 9 > 0)
theSize = NightWatch.imageUrl.size() / 9 + 1;
else
theSize = NightWatch.imageUrl.size() / 9;
mPageAdapter = new ImagePagerAdapter(getChildFragmentManager(), theSize);
mPager.setAdapter(mPageAdapter);
Log.d("size of viewPager Adapter", "" + theSize);
}
public static class ImagePagerAdapter extends FragmentStatePagerAdapter {
int mSize;
public ImagePagerAdapter(FragmentManager fm, int size) {
super(fm);
mSize = size;
}
#Override
public Fragment getItem(int arg0) {
// TODO Auto-generated method stub
Log.d("Starting imageDetailFragment", "");
Log.d("Pager", "Pager starting fragment");
Log.d("GRID", "fuck grid");
if (!isGrid)
return ImageDetailFragment.newInstance(arg0,
NightWatch.hotImageUrl, NightWatch.hotNameList,
NightWatch.hotTrendList, NightWatch.hotDateList);
else
return GridFragment.newInstance(arg0, NightWatch.imageUrl);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return mSize;
}
}
public class CustomSpinnerAdapter extends ArrayAdapter<Integer> {
List<Integer> resourceId;
Context c;
public CustomSpinnerAdapter(Context context, int textViewResourceId,
List<Integer> objects) {
super(context, textViewResourceId, objects);
resourceId = objects;
c = context;
}
#Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
return getCustomDropdownView(position, convertView, parent);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}
public View getCustomView(int position, View convertView,
ViewGroup parent) {
ImageView imageView = new ImageView(c);
imageView.setImageResource(resourceId.get(position));
imageView.setLayoutParams(new ListView.LayoutParams(
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()), (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 34,
getResources().getDisplayMetrics())));
return imageView;
}
public View getCustomDropdownView(int position, View convertView,
ViewGroup parent) {
ImageView imageView = new ImageView(c);
imageView.setImageResource(resourceId.get(position));
imageView.setLayoutParams(new ListView.LayoutParams(
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()), (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 34,
getResources().getDisplayMetrics())));
if (position == 0) {
imageView.setVisibility(View.GONE);
}
return imageView;
}
}
}
I dont see a point in posting the rest of the fragments. The memory leak is somewhere here I'm sure
I would really appreciate it if someone helped me with this.
Loading a Bitmap from a URL in such manner will cause IOException. With Picasso, you don't even need asynctask. Simply call this in UI Thread:
Picasso.with(getActivity())
.load(url)
.into(imageView); //you can add .resize() before .into()
OR if you really want to have the Bitmap, you use this code:
new AsyncTask<Void, Void, Void>() {
Bitmap bitmap;
#Override
protected void onPreExecute() {
//some code
}
#Override
protected Void doInBackground(Void... arg0) {
bitmap = getBitmapFromURL(url);
return null;
}
#Override
protected void onPostExecute(Void result) {
imageView.setImageBitmap(bitmap);
}
}.execute();
And getBitmapFromURL():
public Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
return BitmapFactory.decodeStream(input);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Ok so I would recommend you stick with using Picasso as this will make your life a lot easier in terms of memory management and the likes. One thing to remember is that the image contained in an imageview can ultimately retrieved as a Bitmap regardless of the image type (eg jpeg, png etc), so if you use Picasso to load the image via a URL you can still retrieve the image as a Bitmap after it is loaded and apply your transformation on it. Picasso also have a function called .transform() which you can use to transform your images by supplying a custom transformation. Here is an example for a rounded transformation, first the code that implements the transformation:
//calcualte the raduis for the rounded images
final float scale = mContext.getResources().getDisplayMetrics().density; //get screen density for scale
int pixels = (int) ((imageView.getWidth()-5) * scale); //get screen pixels based on density. Imageview is 60dp x 60dp in size, subtract some padding = 55
mRadiusCenter = pixels / 2; //get the raduis
//now load your image
Picasso.with(mContext)
.load(imageUrl)
.fit().centerCrop()
.transform(new RoundedTransformation(mRadiusCenter))
.into(imageView);
The you need to create a class for the RoundedTransformation that implements Picasso Transformation:
// enables hardware accelerated rounded corners
// original idea here : http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/
public class RoundedTransformation implements com.squareup.picasso.Transformation {
private final int radius;
// radius is corner radii in dp
public RoundedTransformation(final int radius) {
this.radius = radius;
}
#Override
public Bitmap transform(final Bitmap source) {
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
canvas.drawCircle(radius, radius, radius, paint);
if (source != output) {
source.recycle();
}
return output;
}
#Override
public String key() {
return "rounded";
}
}
Here are some more links that might prove useful:
https://gist.github.com/julianshen/5829333
Load large images with Picasso and custom Transform object
Hope that helps!
I have an application which allow to download 3 images and show them into a gallery
In order to do this , i use a thread in order to download the images and a handler in order to put the images into the gallery
The problem is that the images are not displayed(imageviews are empty) into the gallery (even if i see 3 imageview for my 3 images)
I do not know if this is because the connection is very slow (I develop on a mobile) or if it's because the ui is displayed before images are downloaded
Thank you very much for your help
public class ChoiceLanguage extends Activity {
private TextView nomLangue;
private ArrayList<Language> listeLangues;
private ArrayList<String> listImages;
private Gallery gallery;
private String URL="******************";
private Drawable mNoImage;
Bitmap bitmap;
ImageView imgView = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.choice_language);
listeLangues= getIntent().getParcelableArrayListExtra("listeLangues");
listImages=buildListImages();
gallery = (Gallery) findViewById(R.id.galleryImg);
gallery.setAdapter(new AddImgAdp(this));
gallery.setSpacing(10);
gallery.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
System.out.println("URL "+ listImages.get(position) );
}
});
}
private InputStream openHttpConnection(String urlString) throws IOException {
InputStream in = null;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
conn.connect();
in=conn.getInputStream();
return in;
}
private Bitmap downloadImage( ImageView iView, String url) {
Bitmap bitmap = null;
InputStream in = null;
BufferedInputStream bis ;
try {
in = openHttpConnection(url);
bis= new BufferedInputStream(in, 8192);
bitmap = BitmapFactory.decodeStream(bis);
bis.close();
in.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return bitmap;
}
private ArrayList<String> buildListImages() {
ArrayList<String> listImg = new ArrayList<String>();
for(Language l : listeLangues) {
listImg.add(URL+l.getImagePath());
}
return listImg;
}
public class AddImgAdp extends BaseAdapter {
int GalItemBg;
private Context cont;
public AddImgAdp(Context c) {
cont = c;
TypedArray typArray = obtainStyledAttributes(R.styleable.GalleryTheme);
GalItemBg = typArray.getResourceId(R.styleable.GalleryTheme_android_galleryItemBackground, 0);
typArray.recycle();
}
public int getCount() {
return listImages.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
imgView = new ImageView(cont);
} else {
imgView = (ImageView)convertView;
}
ThreadDownload progressDl= new ThreadDownload(position);
progressDl.start();
imgView.setLayoutParams(new Gallery.LayoutParams(150, 150));
imgView.setScaleType(ImageView.ScaleType.FIT_XY);
imgView.setBackgroundResource(GalItemBg);
return imgView;
}
}
private class SetImg extends Handler {
public void handleMessage(Message msg) {
imgView.setImageBitmap(bitmap);
}
}
private class ThreadDownload extends Thread {
SetImg img= new SetImg();
int position ;
public ThreadDownload(int position)
{
super();
this.position=position;
}
public void run() {
bitmap = downloadImage(imgView,listImages.get(position));
img.sendEmptyMessage(0);
}
}
}
You can make use of SmartImageView, it is a drop-in replacement for Android’s standard ImageView which additionally allows images to be loaded from URLs or the user’s contact address book. Images are cached to memory and to disk for super fast loading.
https://github.com/loopj/android-smart-image-view
I'm developping a thumbnail mosaic of all pictures on SdCard.
If the user longclick on a picture, i want to start drag and drop process.
I clearly manage to get all images files and showing them with my own BaseAdapter in a GridView, but the process is long because I create previews of each image this way :
uri = Uri.fromFile(file);
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
if (bitmap != null) {
newBitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
bitmap.recycle();
// here code to add the bitmap to the adapter (see after)
}
} catch (IOException e) {
//Error fetching image, try to recover
}
So in order to avoid long wait, I'm loading the images in a AsyncTask.
The process work well and the images appears one by one, but now an error appear on LongClick, in this code :
mGrid.setOnItemLongClickListener(new OnItemLongClickListener()
{
public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id)
{
ClipData data = ClipData.newPlainText("AdapterPosition", String.valueOf(position) );
view.startDrag(data, new DragShadowBuilder(view), null, 0);
return true;
}
});
and the error :
12-27 16:54:14.980: E/View(8089): Unable to initiate drag
12-27 16:54:14.980: E/View(8089): java.lang.NullPointerException
12-27 16:54:14.980: E/View(8089): at android.view.View.startDrag(View.java:11470)
12-27 16:54:14.980: E/View(8089): at renault.limandroid.widget.PartageWidgetActivity$9.onItemLongClick(PartageWidgetActivity.java:547)
Is someone have a idea?
Here is a large part of my code :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_partage_widget);
// ... //
mImageAdapter = new ImageAdapter(this);
loadImages();
mGrid.setOnItemLongClickListener(new OnItemLongClickListener()
{
public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id)
{
ClipData data = ClipData.newPlainText("AdapterPosition", String.valueOf(position) );
view.startDrag(data, new DragShadowBuilder(view), null, 0);
return true;
}
});
mGrid.setAdapter(mImageAdapter);
}
private void loadImages()
{
// si c'est la première fois qu'on passe ici
if (mLoadImageTask.getStatus() == AsyncTask.Status.PENDING)
{
mLoadImageTask.execute();
}
// si le scan est terminé mais qu'on veut le remettre à jour
// on va recréer la tâche
else if (mLoadImageTask.getStatus() == AsyncTask.Status.FINISHED)
{
mLoadImageTask = new LoadImagesFromSDCard();
mLoadImageTask.execute();
}
}
#Override
protected Object doInBackground(Object... params) {
setProgressBarIndeterminateVisibility(true);
Log.d(TAG,"LoadImages - do in background");
Bitmap bitmap = null;
Bitmap newBitmap = null;
Uri uri = null;
List<File> listFiles = new ArrayList<File>();
listFiles = StorageManager.findImageFiles();
for (File file : listFiles)
{
// mImageListFile contains the files that have already been loaded
if (!mImageListFile.contains(file))
{
uri = Uri.fromFile(file);
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
if (bitmap != null) {
newBitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
bitmap.recycle();
if (newBitmap != null) {
publishProgress(new LoadedImage(newBitmap));
}
}
} catch (IOException e) {
//Error fetching image, try to recover
}
mImageListFile.add(file);
}
}
return null;
}
/**
* Add a new LoadedImage in the images grid.
*
* #param value The image.
*/
#Override
public void onProgressUpdate(LoadedImage... value)
{
mImageAdapter.addPhoto(value[0]);
mImageAdapter.notifyDataSetChanged();
}
/**
* Set the visibility of the progress bar to false.
*
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(Object result)
{
setProgressBarIndeterminateVisibility(false);
mGrid.invalidate();
}
}
class ImageAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>();
public ImageAdapter(Context context) {
mContext = context;
photos.add(new LoadedImage(BitmapFactory.decodeResource(context.getResources(),
R.drawable.click)));
}
public void addPhoto(LoadedImage photo)
{
photos.add(photo);
}
public int getCount() {
return photos.size();
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent)
{
final ImageView imageView;
final int pos = position;
if (convertView == null) {
imageView = new ImageView(mContext);
} else {
imageView = (ImageView) convertView;
}
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setPadding(2, 2, 2, 2);
imageView.setLayoutParams(new GridView.LayoutParams(parent.getWidth()/4, parent.getWidth()/4));
imageView.setImageBitmap(photos.get(position).getBitmap());
return imageView;
}
public Object getItem(int position)
{
return photos.get(position);
}
}
/**
* A LoadedImage contains the Bitmap loaded for the image.
*/
private static class LoadedImage {
Bitmap mBitmap;
LoadedImage(Bitmap bitmap) {
mBitmap = bitmap;
}
public Bitmap getBitmap() {
return mBitmap;
}
}