developing an image picker using recyclerview with all images in devices for an android app, facing an issue when user scroll through images its memory usage keeps increasing eventually if lots of images there is oom exception, have searched for this issue over the internet, have applied several techniques but it is of little use, i have seen other app(whatsapp, olx) its picker scrolling is nice and no oom, i also tried dump heap in android studio to detect memory leakage, i found that there are as many viewholders as number of images, its not being recycled, am not able to find the reason, please help me in detecting the issue, attaching code..
/** adapter class for grid recyclerview*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<CreateList> galleryList;
private Context context;
private List<String> imageUrls = new ArrayList<>(3);
private List<Integer> positionList = new ArrayList<>(3);
int count = 0;
RequestOptions options;
RequestBuilder glide;
RequestManager glideMain;
int imgWidth;
public MyAdapter(Context context, ArrayList<CreateList> galleryList, RequestOptions options, RequestBuilder<Bitmap> glide, RequestManager glideMain, int imgWidth) {
this.galleryList = galleryList;
this.context = context;
this.options = options;
this.glide = glide;
this.glideMain = glideMain;
this.imgWidth = imgWidth;
}
#Override
public void onViewRecycled(#NonNull ViewHolder holder) {
holder.img.setOnClickListener(null);
holder.img.setColorFilter(null);
holder.img.setImageDrawable(null);
if(holder.title.getText().toString().equals("1")){
}
//holder.itemView.setOnClickListener(null);
glideMain.clear(holder.img);
super.onViewRecycled(holder);
}
#Override
public void onViewDetachedFromWindow(#NonNull ViewHolder holder) {
/* holder.img.setOnClickListener(null);
holder.img.setColorFilter(null);*/
holder.img.setImageDrawable(null);
// holder.itemView.setOnClickListener(null);
glideMain.clear(holder.img);
super.onViewDetachedFromWindow(holder);
}
#Override
public void onViewAttachedToWindow(#NonNull final ViewHolder holder) {
/* holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
holder.handleThumbnail(view);
}
});*/
super.onViewAttachedToWindow(holder);
}
public ArrayList<CreateList> getGalleryList() {
return galleryList;
}
public void setGalleryList(ArrayList<CreateList> galleryList) {
this.galleryList = galleryList;
}
public List<Integer> getPositionList() {
return positionList;
}
public void setPositionList(List<Integer> positionList) {
this.positionList = positionList;
}
public List<String> getImageUrls() {
return imageUrls;
}
public void setImageUrls(List<String> imageUrls) {
this.imageUrls = imageUrls;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cell_layout, viewGroup, false);
//img.setOnClickListener();
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, int pos) {
glide
.load(galleryList.get(pos).getImage_Location())
.thumbnail(0.1F)
.apply(options)
.into(viewHolder.img);
if (positionList.contains(pos)){
// view not selected
//viewHolder.parent.setBackgroundColor(Color.LTGRAY);
viewHolder.title.setVisibility(View.VISIBLE);
viewHolder.title.setText(String.valueOf(positionList.indexOf(pos)+1));
viewHolder.img.setColorFilter(viewHolder.getColorWithAlpha(Color.GREEN, 0.3f));
}
}
#Override
public int getItemCount() {
return galleryList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView title;
private ImageView img;
public ViewHolder(View view) {
super(view);
title = (TextView)view.findViewById(R.id.highlightText);
img = (ImageView) view.findViewById(R.id.img);
/* view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handleThumbnail(v);
}
});*/
/* img = view.findViewById(R.id.img);*/
img.setLayoutParams(new ConstraintLayout.LayoutParams(imgWidth, imgWidth));
/*img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// This is OnClick of any list Item
handleThumbnail(v);
}
});*/
/* img.setOnTouchListener(new View.OnTouchListener() {
private Rect rect;
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
img.setColorFilter(Color.argb(50, 0, 0, 0));
rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
}
if(event.getAction() == MotionEvent.ACTION_UP){
img.setColorFilter(Color.argb(0, 0, 0, 0));
}
if(event.getAction() == MotionEvent.ACTION_MOVE){
if(!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())){
img.setColorFilter(Color.argb(0, 0, 0, 0));
}
}
return false;
}
});*/
}
public void handleThumbnail(View v) {
if(!imageUrls.contains(galleryList.get(getAdapterPosition()).getImage_Location())) {
if(count<3) {
positionList.add(getAdapterPosition());
String selectedImgUrl = galleryList.get(getAdapterPosition()).getImage_Location();
imageUrls.add(selectedImgUrl);
//img.setBackground(context.getResources().getDrawable(R.drawable.button_background_checked));
img.setColorFilter(getColorWithAlpha(Color.GREEN, 0.3f));
//title.setVisibility(View.VISIBLE);
//title.setText(String.valueOf(count+1));
//View viewSelected = gridRecycler.findViewHolderForAdapterPosition(position).itemView;
title.setVisibility(View.VISIBLE);
title.setText(String.valueOf(count+1));
count++;
} else {
Toast.makeText().show();
}
} else {
imageUrls.remove(galleryList.get(getAdapterPosition()).getImage_Location());
positionList.remove(new Integer(getAdapterPosition()));
//imageUrls.remove( Integer.parseInt(title.getText().toString()));
title.setVisibility(View.GONE);
count--;
// img.setBackground(context.getResources().getDrawable(R.drawable.button_background));
img.setColorFilter(Color.argb(0, 0, 0, 0));
EventBus.getDefault().post(new MessageEvent(imageUrls, positionList));
}
}
public int getColorWithAlpha(int color, float ratio) {
int newColor = 0;
int alpha = Math.round(Color.alpha(color) * ratio);
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
newColor = Color.argb(alpha, r, g, b);
return newColor;
}
}
activity code using background thread to load data and set in adapter:
private class PrepareData extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int imgWidth = (int) (displayMetrics.widthPixels*0.32);
RequestOptions options = new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.override(imgWidth/3)
.dontAnimate()
.centerCrop()
.skipMemoryCache(true);
final RequestManager glide = Glide.with(gridRecycler.getContext());
RequestBuilder builder = glide.asBitmap();
gridRecycler.setHasFixedSize(true);
final RecyclerView.LayoutManager layoutManager = new GridLayoutManager(gridRecycler.getContext(), 3);
createLists = getAllFolderImages(this);
adapter = new MyAdapter(this, createLists, options, builder, glide, imgWidth);
gridRecycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
glide.resumeRequests();
}
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL || newState==AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
glide.pauseRequests();
System.gc();
}
}
});
runOnUiThread(new Runnable() {
#Override
public void run() {
gridRecycler.setLayoutManager(layoutManager);
gridRecycler.setAdapter(adapter);
//put the code here that is giving exception
}
});
return null;
}
}
android profiling screen-shot, its visible that viewholder is consuming lots of memory and has lots of instances.
Related
I'm facing this issue only on android Nougat. After drag and dropping an item, the OnClick event doesn't fire on this item anymore.
Here's the adapter :
public class VideoListAdapter extends RecyclerView.Adapter<VideoListAdapter.VideoListViewHolder> implements ItemTouchHelperAdapter {
private List<Media> videos;
private LayoutInflater inflater;
private Context context;
private int selectedItemPosition;
private Media selectedMedia;
private static final int NOTHING_SELECTED = -1;
public VideoListAdapter(Context context, List<Media> videos, Delegate delegate) {
inflater = LayoutInflater.from(context);
setVideos(videos);
this.context = context;
setSelectedItem(NOTHING_SELECTED);
}
public void setSelectedItem(int pos) {
selectedItemPosition = pos;
if(pos != NOTHING_SELECTED)
selectedMedia = videos.get(pos);
else
selectedMedia = null;
}
public void setVideos(List<Media> videos) {
this.videos = videos;
setSelectedItem(NOTHING_SELECTED);
}
private void onVideosReordered() {
if(selectedMedia != null)
setSelectedItem(videos.indexOf(selectedMedia));
}
public void unselectAll() {
setSelectedItem(NOTHING_SELECTED);
notifyDataSetChanged();
}
#Override
public VideoListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.item_video_list, parent, false);
return new VideoListViewHolder(view);
}
#Override
public void onBindViewHolder(final VideoListViewHolder holder, int position) {
String imagePath = videos.get(position).getFilePath();
boolean isEmptyItem = imagePath == null || imagePath.isEmpty();
if (isEmptyItem) {
holder.video_list_item_selected.setVisibility(View.GONE);
holder.img_image.setVisibility(View.GONE);
} else {
UtilsMedia.loadThumbnailImageNoSpinAnimation(holder.img_image, imagePath);
boolean isSelected = selectedItemPosition == position;
if (isSelected && !isEmptyItem)
holder.video_list_item_selected.setVisibility(View.VISIBLE);
else
holder.video_list_item_selected.setVisibility(View.GONE);
}
}
#Override
public int getItemCount() {
return videos.size();
}
#Override
public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++)
Collections.swap(videos, i, i + 1);
} else {
for (int i = fromPosition; i > toPosition; i--)
Collections.swap(videos, i, i - 1);
}
notifyItemMoved(fromPosition, toPosition);
return true;
}
#Override
public void onItemDropped() {
onVideosReordered();
notifyDataSetChanged();
}
class VideoListViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
public ImageView img_image;
public ImageView video_list_item_selected;
public FrameLayout fl_root;
public Context context;
public boolean isSelected;
private static final String TAG = "VideoListViewHolder";
public VideoListViewHolder(View view) {
super(view);
img_image = (ImageView) view.findViewById(R.id.img_image);
video_list_item_selected = (ImageView) view.findViewById(R.id.video_list_item_selected);
fl_root = (FrameLayout) view.findViewById(R.id.fl_root);
context = view.getContext();
isSelected = false;
fl_root.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int currentPosition = getAdapterPosition();
if (selectedItemPosition == currentPosition) {
setSelectedItem(NOTHING_SELECTED);
} else {
if (selectedItemPosition != -1)
notifyItemChanged(selectedItemPosition);
setSelectedItem(currentPosition);
}
notifyItemChanged(currentPosition);
}
});
}
#Override
public void onItemSelected() {
final Animation zoomOut = AnimationUtils.loadAnimation(context, R.anim.zoom_out);
zoomOut.setDuration(300);
fl_root.startAnimation(zoomOut);
}
#Override
public void onItemClear() {
final Animation zoomIn = AnimationUtils.loadAnimation(context, R.anim.zoom_in);
zoomIn.setDuration(300);
fl_root.startAnimation(zoomIn);
}
}
}
And here is the item touch helper callback :
public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
public static final float ALPHA_FULL = 1.0f;
protected final ItemTouchHelperAdapter mAdapter;
public ItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
mAdapter = adapter;
}
#Override
public boolean isLongPressDragEnabled() {
return true;
}
#Override
public boolean isItemViewSwipeEnabled() {
return false;
}
#Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
final int swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
}
private int moveSource = -1;
private int moveTarget = -1;
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
if (source.getItemViewType() != target.getItemViewType())
return false;
if(moveSource == -1)
moveSource = source.getAdapterPosition();
moveTarget = target.getAdapterPosition();
mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
return true;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
}
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemSelected();
}
super.onSelectedChanged(viewHolder, actionState);
}
#Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setAlpha(ALPHA_FULL);
if (viewHolder instanceof ItemTouchHelperViewHolder) {
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemClear();
}
if(moveSource != -1 && moveTarget != -1 && moveSource != moveTarget)
mAdapter.onItemDropped();
moveSource = moveTarget = -1;
}
}
Any help would be appreciated, thanks !
I had to remove every notifyDataSet changed and replace them by other notifyXXX (notifyItemRangeInserted, notifyItemRangeRemoved, notifyItemRangeChanged, etc)
This is my code in which the image is not showing properly:
public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.PhotoViewHolder> implements SizeCalculatorDelegate {
ArrayList<String> source_title = new ArrayList<String>();
private final double[] mImageAspectRatios;
private Context mContext;
public double aspectRatioForIndex(int index) {
// Precaution, have better handling for this in greedo-layout
if (index >= getItemCount()) return 1.0;
return mImageAspectRatios[getLoopedIndex(index)];
}
public class PhotoViewHolder extends RecyclerView.ViewHolder {
private ImageView mImageView;
public PhotoViewHolder(ImageView imageView) {
super(imageView);
mImageView = imageView;
}
}
public MoviesAdapter(Context context, ArrayList<String> image) {
mContext = context;
this.source_title = image;
mImageAspectRatios = new double[source_title.size()];
// calculateImageAspectRatios();
}
#Override
public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ImageView imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
return new PhotoViewHolder(imageView);
}
#Override
public void onBindViewHolder(final PhotoViewHolder holder, int position) {
Picasso.with(mContext).load(source_title.get(position)).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
holder.mImageView.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.d("bitmapfailed", "errorDrawable " + errorDrawable);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d("onPrepareLoad", "placeHolderDrawable " + placeHolderDrawable);
}
});
}
#Override
public int getItemCount() {
return source_title.size();
}
// private void calculateImageAspectRatios() {
// BitmapFactory.Options options = new BitmapFactory.Options();
// options.inJustDecodeBounds = true;
//
// for (int i = 0; i < source_title.size(); i++) {
//
// int value = Integer.parseInt(source_title.get(i));
//
// BitmapFactory.decodeResource(mContext.getResources(), value, options);
// mImageAspectRatios[i] = options.outWidth / (double) options.outHeight;
// }
// }
// Index gets wrapped around <code>Constants.IMAGES.length</code> so we can loop content.
private int getLoopedIndex(int index) {
return index % source_title.size(); // wrap around
}
}
and this is the original demo code
public class PhotosAdapter extends RecyclerView.Adapter<PhotosAdapter.PhotoViewHolder> implements SizeCalculatorDelegate {
private static final int IMAGE_COUNT = 500; // number of images adapter will show
private final int[] mImageResIds = Constants.IMAGES;
private final double[] mImageAspectRatios = new double[mImageResIds.length];
private Context mContext;
#Override
public double aspectRatioForIndex(int index) {
// Precaution, have better handling for this in greedo-layout
if (index >= getItemCount()) return 1.0;
Log.d("index", mImageAspectRatios + "");
return mImageAspectRatios[getLoopedIndex(index)];
}
public class PhotoViewHolder extends RecyclerView.ViewHolder {
private ImageView mImageView;
public PhotoViewHolder(ImageView imageView) {
super(imageView);
mImageView = imageView;
}
}
public PhotosAdapter(Context context) {
mContext = context;
calculateImageAspectRatios();
}
#Override
public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ImageView imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
return new PhotoViewHolder(imageView);
}
#Override
public void onBindViewHolder(PhotoViewHolder holder, int position) {
Picasso.with(mContext)
.load(mImageResIds[getLoopedIndex(position)])
.into(holder.mImageView);
}
#Override
public int getItemCount() {
return IMAGE_COUNT;
}
private void calculateImageAspectRatios() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
for (int i = 0; i < mImageResIds.length; i++) {
BitmapFactory.decodeResource(mContext.getResources(), mImageResIds[i], options);
mImageAspectRatios[i] = options.outWidth / (double) options.outHeight;
}
}
// Index gets wrapped around <code>Constants.IMAGES.length</code> so we can loop content.
private int getLoopedIndex(int index) {
return index % Constants.IMAGES.length; // wrap around
}
}
in this demo the image shows properly but in my demo images not show, tha data from source_title arraylist is showing properly but this demo does not work properly, as I use onBindViewHolder method it goes into onPrepareLoad exception called null value of placeHolderDrawable...
Is there any solution to use it or some other method or way to solve this issue?
Sorry for my english and thnx in advance...
I am new to Android development and currently I am implementing Live wallpaper application.So, My question is How I can change live wallpaper when new live wallpaper is selected from the application.currently I am setting only one live wallpaper from my application but issue is that when I am selecting wallpaper from my application to set as wallpaper it is not change and display previously selected wallpaper.And when i am restarting my device then it will display.I am using Glide library to display Gif image.
Here this my WallpaperService class
public class GifPaperService extends WallpaperService {
static final String TAG = "gifService";
static final Handler gifHandler = new Handler();
int position;
boolean visible;
ImageAdapter img = new ImageAdapter();
Integer[] mThumb = img.mThumbIds;
#Override
public void onCreate() {
super.onCreate();
Log.v("Helllo", "...");
}
#Override
public Engine onCreateEngine() {
try {
return new GifEngine();
} catch (IOException e) {
Log.w(TAG, "Error creating engine", e);
stopSelf();
return null;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v("Hello..", ".....");
return super.onStartCommand(intent, flags, startId);
}
class GifEngine extends Engine {
private final Movie gif;
private final int duration;
private final Runnable runnable;
float scaleX;
float scaleY;
int when;
long start;
GifEngine() throws IOException {
MyPreferenceActivity myPref = new MyPreferenceActivity(getApplicationContext());
Log.i("Imageis... ", "Position.." + myPref.getGifImage());
position = myPref.getGifImage();
InputStream is = getResources().openRawResource(mThumb[position]);
Log.i("Imageposition...", "...." + mThumb[position]);
if (is == null) {
throw new IOException("Unable to open whoa.gif");
}
try {
gif = Movie.decodeStream(is);
duration = gif.duration();
} finally {
is.close();
}
when = -1;
runnable = new Runnable() {
#Override
public void run() {
animateGif();
}
};
}
#Override
public void onDestroy() {
super.onDestroy();
gifHandler.removeCallbacks(runnable);
}
#Override
public void onVisibilityChanged(boolean visible) {
super.onVisibilityChanged(visible);
if (visible) {
animateGif();
} else {
gifHandler.removeCallbacks(runnable);
}
}
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
scaleX = width / (1f * gif.width());
scaleY = height / (1f * gif.height());
animateGif();
}
#Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xOffsetStep, float yOffsetStep,
int xPixelOffset, int yPixelOffset) {
super.onOffsetsChanged(
xOffset, yOffset,
xOffsetStep, yOffsetStep,
xPixelOffset, yPixelOffset);
animateGif();
}
void animateGif() {
tick();
SurfaceHolder surfaceHolder = getSurfaceHolder();
Canvas canvas = null;
try {
canvas = surfaceHolder.lockCanvas();
if (canvas != null) {
gifCanvas(canvas);
}
} finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
gifHandler.removeCallbacks(runnable);
if (isVisible()) {
gifHandler.postDelayed(runnable, 1000L / 25L);
}
}
void tick() {
if (when == -1L) {
when = 0;
start = SystemClock.uptimeMillis();
} else {
long diff = SystemClock.uptimeMillis() - start;
when = (int) (diff % duration);
}
}
void gifCanvas(Canvas canvas) {
canvas.save();
canvas.scale(scaleX, scaleY);
gif.setTime(when);
gif.draw(canvas, 0, 0);
canvas.restore();
}
#Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
stopSelf();
gifHandler.removeCallbacks(runnable);
}
}
}
Activity class for setting wallpaper
setWallpaper.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT > 15) {
Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, new ComponentName(mContext, GifPaperService.class));
startActivity(intent);
}
}
});
ImageAdapter:
public class ImageAdapter extends BaseAdapter {
static WallpaperInfo info;
private Context mContext;
public ImageAdapter() {
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return mThumbIds[position];
}
public long getItemId(int position) {
return 0;
}
public ImageAdapter(Context c) {
mContext = c;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null){
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(3, 3, 3, 3);
imageView.setMaxHeight(300);
imageView.setMaxWidth(300);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyPreferenceActivity myPref = new MyPreferenceActivity(mContext);
myPref.setGifImage(position);
Intent intent = new Intent(mContext, FullScreenImage.class);
intent.putExtra("imageID", mThumbIds[position]);
/*intent.putExtra(EXTRA_LIVE_WALLPAPER_INTENT, intent);
intent.putExtra(EXTRA_LIVE_WALLPAPER_SETTINGS, info.getSettingsActivity());
intent.putExtra(EXTRA_LIVE_WALLPAPER_PACKAGE, info.getPackageName());*/
mContext.startActivity(intent);
}
});
Animation anim = AnimationUtils.loadAnimation(mContext.getApplicationContext(), R.anim.fly);
imageView.setAnimation(anim);
anim.start();
}
else{
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
public Integer[] mThumbIds = {
R.drawable.gpp1, R.drawable.gpp2,
R.drawable.gpp3,R.drawable.gpp4,
R.drawable.gpp5,R.drawable.gpp6,
R.drawable.gpp7,R.mipmap.h8,
R.mipmap.h9,R.mipmap.h10,
R.mipmap.h11,R.drawable.gp3,
R.drawable.gp2,R.drawable.gp,
R.drawable.onehalloween
};
}
If anyone know what is the problem.Tell me.
Thank in advance
For destroying previous wallpaper and setting new wallpaper,You have to Clear previous wallpaper like this,
In Your setWallpaper button click event use this code,
setWallpaper.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT > 16) {
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.clear();
} catch (IOException e) {
e.printStackTrace();
}
Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, new ComponentName(mContext, GifPaperService.class));
Log.i("Intent....", "...." + intent);
startActivity(intent);
}
}
});
This is works for me...
This is my PhotosAdapter class for loading images with changing heigh or width.
import com.fivehundredpx.greedolayout.GreedoLayoutSizeCalculator.SizeCalculatorDelegate;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
import java.util.ArrayList;
/**
* Created by Julian Villella on 16-02-24.
*/
public class PhotosAdapter extends RecyclerView.Adapter<PhotosAdapter.PhotoViewHolder> implements SizeCalculatorDelegate {
private static final int IMAGE_COUNT = 500;
// private final double[] mImageAspectRatios = new double[Constants.IMAGES.length];
ArrayList<String> source_title = new ArrayList<String>();
ArrayList<String> mImageResIds = new ArrayList<String>();
private Context mContext;
// #Override
// public double aspectRatioForIndex(int index) {
// // Precaution, have better handling for this in greedo-layout
// if (index >= getItemCount()) return 1.0;
// return mImageAspectRatios[getLoopedIndex(index)];
// }
#Override
public double aspectRatioForIndex(int index) {
// Precaution, have better handling for this in greedo-layout
if (index >= getItemCount()) return 1.0;
return mImageResIds.size();
}
public class PhotoViewHolder extends RecyclerView.ViewHolder {
private ImageView mImageView;
public PhotoViewHolder(ImageView imageView) {
super(imageView);
mImageView = imageView;
Log.d("PhotoViewHolderimage", imageView + "");
}
}
public PhotosAdapter(Context context, ArrayList<String> source_title, ArrayList<String> source_filepath) {
mContext = context;
this.mImageResIds = source_filepath;
this.source_title = source_title;
Log.d("start", "start" + mImageResIds);
// calculateImageAspectRatios();
}
#Override
public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ImageView imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
Log.d("PhotoViewHoldermake", imageView + "");
return new PhotoViewHolder(imageView);
}
#Override
public void onBindViewHolder(final PhotoViewHolder holder, int position) {
// Picasso.with(mContext)
// .load(mImageResIds.get(position))
// .into(holder.mImageView);
Log.d("onBindViewHolder", holder + "");
Log.d("mImageResIds", mImageResIds.get(position));
Picasso.with(mContext).load(mImageResIds.get(position)).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
holder.mImageView.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.d("Imageloadingfailed", " " + errorDrawable);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d("Imageloading", "placeHolderDrawable " + placeHolderDrawable);
}
});
}
#Override
public int getItemCount() {
return mImageResIds.size();
}
// private void calculateImageAspectRatios() {
// BitmapFactory.Options options = new BitmapFactory.Options();
// options.inJustDecodeBounds = true;
//
// for (int i = 0; i < mImageResIds.size(); i++) {
// BitmapFactory.decodeResource(mContext.getResources(), mImageResIds.indexOf(i), options);
// mImageAspectRatios[i] = options.outWidth / (double) options.outHeight;
// }
// }
// Index gets wrapped around <code>Constants.IMAGES.length</code> so we can loop content.
// private int getLoopedIndex(int index) {
// return index % Constants.IMAGES.length; // wrap around
// }
}
When this class run , data is there but not showing the image ,the onBindViewHolder method runs and there is an issue and due to this issue the picasso Override method onPrepareLoad and it shows the placeHolderDrawable null exception
i m using this code as reference https://github.com/500px/greedo-layout-for-android
If any one have any solution or any suggestion regarding this issue please help me out of this issue.
Sorry for my english and thanks in advance.
I am trying to make the items in a recyclerview to move when scrolling up or down in a matter which depends on the the Y coordinate of the child views. However I can't seem to be able to get the coordinate of the children.
How can I get the Y coordinate?
I need it in the onBindViewHolder method so that I can set the layout param of the child view according to it.
in your Activity/Fragment :
RecyclerView yourRecyclerView;
FansAdapter yourRecyclerAdapter;
........
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
yourRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
yourRecyclerView.setLayoutManager(new LinearLayoutManager(this));
yourRecyclerView.setHasFixedSize(true);
yourRecyclerAdapter = new YourAdapter (populateYourList(), this);
yourRecyclerView.setAdapter(yourRecyclerAdapter);
yourRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
View firstVisibleChild = recyclerView.getChildAt(0);//change if necessary. determine that item(items) you need to find
final ImageView imageView = (ImageView) firstVisibleChild.findViewById(R.id.item_image);
if (null != imageView) {
imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int[] locationsFrom = new int[2];
imageView.getLocationInWindow(locationsFrom);
int xStart = locationsFrom[0];
int yStart = locationsFrom[1];
Log.d("LOG_TAG", "your item xEnd=" + xStart +" yEnd=" + yStart);
if (null != yourRecyclerAdapter) {
yourRecyclerAdapter.setX(xStart);
yourRecyclerAdapter.setY(yStart);
}
}
}
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
if (null != yourRecyclerView) {
yourRecyclerView.clearOnScrollListeners();
}
}
and Adapter:
public class YourAdapter extends RecyclerView.Adapter<YourAdapter.YouViewHolder> {
ArrayList<String> fansList;
Context mContext;
private int x;
private int y;
public YourAdapter(ArrayList<String> fansList, Context context) {
this.fansList = fansList;
this.mContext = context;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
#Override
public YouViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
if (viewGroup instanceof RecyclerView) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycle_item_fans, viewGroup, false);
view.setFocusable(true);
return new YouViewHolder(view);
} else {
throw new RuntimeException("Not bound to RecyclerView");
}
}
#Override
public void onBindViewHolder(YouViewHolder holder, int position) {
holder.itemName.setText(fansList.get(position));
Log.v("LOG_TAG","x="+x+" y="+y);// use y or x
}
#Override
public int getItemCount() {
return fansList.size();
}
//holder
public final class YouViewHolder extends RecyclerView.ViewHolder {
public final TextView itemName;
public final ImageView imageView;
public YouViewHolder(View rowView) {
super(rowView);
this.itemName = (TextView) rowView.findViewById(R.id.text_fan_name);
this.imageView = (ImageView) rowView.findViewById(R.id.image_second_free);
}
}
}