I'm using an adapter view for for a list view to retrieve " Publications " from Parse.com, I'm using an animation for loading image from Parse. and i'm using another function to get a circle view of the image.
all is working great, the loading is perfect but when I slide down/up on the list view the image is animated again each time I slide Up/Down. and I couldn't stop that.
here is the code of my adapter :
public class adapterview extends ArrayAdapter<Message> {
Bitmap image;
public adapterview(Context context, ArrayList<Message> Messages) {
super(context, 0, Messages);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
final Message m = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom2, parent, false);
}
TextView message = (TextView) convertView.findViewById(R.id.message);
TextView date = (TextView) convertView.findViewById(R.id.date);
TextView user = (TextView) convertView.findViewById(R.id.user);
message.setText(m.getMessage());
user.setText(m.getUser());
new DownloadImageTask((ImageView) convertView.findViewById(R.id.imageView1))
.execute(m.getImage());
return convertView;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
TransitionDrawable td = new TransitionDrawable(new Drawable[]{
new ColorDrawable(android.R.color.transparent),
new BitmapDrawable(getContext().getResources(), getCircleBitmap(result))
});
bmImage.setImageDrawable(td);
td.startTransition(2000);
}
}
private Bitmap getCircleBitmap(Bitmap bitmap) {
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final int color = Color.RED;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
bitmap.recycle();
return output;
}
}
if you need any other information you think could be helpful for you to determine the problem just let me know
When a list needs to display a item it calls its Adapters getView() function. When you scroll and list items are no longer visible they are release and not kept in memory.
When scrolling every list item has DownloadImageTask() executed each time it becomes visible. The downloaded image from function is stored only in the ImageView of list item, so is it released from memory as soon as you scroll the list item.
The solution is to store the downloaded image then in getView() function assign the image into the ImageView.
Related
I need to create and set customize bitmap image on each row of listview. I am doing that using picasso. My code inside getView of adapter is like below,
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
View rowView = convertView;
if (rowView == null){
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.horizontal_listview_list_sample, parent, false);
viewHolder = new ViewHolder();
viewHolder.imgDot = (ImageView) rowView.findViewById(R.id.rowIcon);
viewHolder.rowIconBackround = (ImageView) rowView.findViewById(R.id.rowIconBackground);
rowView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) rowView.getTag();
}
//Start Custom Image View///////
String photoUrl1 = arrayList.get(position).getPhotoUrl();
if (photoUrl1.length()<8){
photoUrl1 = "SOME_URL";
}
final String photoUrl = photoUrl1;
final ImageView imgDot = viewHolder.imgDot;
// final viewHolder.imgDot = (ImageView) rowView.findViewById(R.id.rowIcon);
final View finalRowView = rowView;
final ViewHolder finalViewHolder = viewHolder;
final Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap2, Picasso.LoadedFrom from) {
Log.d("PICASO", " called: " + "onBitmapLoaded called");
Bitmap original;
original = new MyProfile().getResizedBitmap(bitmap2, (int) new MainActivity().dipToPixels(MainActivity.getInstance(), 63), (int) new MainActivity().dipToPixels(MainActivity.getInstance(), 63));
BitmapDrawable bitmap = (BitmapDrawable) finalRowView.getResources().getDrawable(R.drawable.drawer_pro_pic_placeholder);
int bitmapHeight= bitmap .getBitmap().getHeight();
int bitmapWidth = bitmap .getBitmap().getWidth();
Bitmap mask = BitmapFactory.decodeResource(finalRowView.getResources(), R.drawable.drawer_pro_pic_placeholder);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
int width = mask.getWidth();
int height = mask.getHeight();
float centerX = (width - original.getWidth()) * 0.5f;
float centerY = (height- original.getHeight()) * 0.5f;
mCanvas.drawBitmap(original, centerX, centerY, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
imgDot.getLayoutParams().height = bitmapHeight;
imgDot.getLayoutParams().width = bitmapWidth;
imgDot.setScaleType(ImageView.ScaleType.CENTER_CROP);
imgDot.setImageBitmap(result);
imgDot.setAdjustViewBounds(true);
Picasso.with(context).cancelRequest(finalViewHolder.imgDot);
targets.remove(this);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.d("PICASO", " called: " + "onBitmapFailed called");
Picasso.with(context).cancelRequest(finalViewHolder.imgDot);
targets.remove(this);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d("PICASO", "responseForRegistration called: " + "onPrepareLoad called");
}
};
targets.add(target);
// imgDot.setTag(target);
Picasso.with(context).load(photoUrl).into(target);
//End Custom Image View////////////
return rowView;
}
Suppose, there is two row so two customize bitmap will be created. When first one is created its showing nice but when second one created then this last image is showing in both row's imageview.
What I need to change in my code?
Any help will be appreciated.
You could try something by creating handler as subclass of your adapter and passing specific reference of your view holder and position which will help us to avoid overriding issue of target listener
// construct the handler inside your adapter's constructor so you know it is on the UI thread
Handler myHandler = new Handler();
class LoadImage implements Runnable {
ImageView iv;
int position;
public LoadImage(ImageView iv, int position) {
this.iv = iv;
this.position = position;
}
#Override
public void run() {
// keep your target listener stuffs here
Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap2, Picasso.LoadedFrom from) {
Log.d("PICASO", " called: " + "onBitmapLoaded called");
Bitmap original;
original = new MyProfile().getResizedBitmap(bitmap2, (int) new MainActivity().dipToPixels(MainActivity.getInstance(), 63), (int) new MainActivity().dipToPixels(MainActivity.getInstance(), 63));
BitmapDrawable bitmap = (BitmapDrawable) finalRowView.getResources().getDrawable(R.drawable.drawer_pro_pic_placeholder);
int bitmapHeight= bitmap .getBitmap().getHeight();
int bitmapWidth = bitmap .getBitmap().getWidth();
Bitmap mask = BitmapFactory.decodeResource(finalRowView.getResources(), R.drawable.drawer_pro_pic_placeholder);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
int width = mask.getWidth();
int height = mask.getHeight();
float centerX = (width - original.getWidth()) * 0.5f;
float centerY = (height- original.getHeight()) * 0.5f;
mCanvas.drawBitmap(original, centerX, centerY, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
iv.getLayoutParams().height = bitmapHeight;
iv.getLayoutParams().width = bitmapWidth;
iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
iv.setImageBitmap(result);
iv.setAdjustViewBounds(true);
Picasso.with(context).cancelRequest(iv);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.d("PICASO", " called: " + "onBitmapFailed called");
Picasso.with(context).cancelRequest(iv);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d("PICASO", "responseForRegistration called: " + "onPrepareLoad called");
}
};
Picasso.with(context).load(photoList.get(position)).into(target);
}
}
And you will call it from your getView by :
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
View rowView = convertView;
if (rowView == null){
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.horizontal_listview_list_sample, parent, false);
viewHolder = new ViewHolder();
viewHolder.imgDot = (ImageView) rowView.findViewById(R.id.rowIcon);
viewHolder.rowIconBackround = (ImageView) rowView.findViewById(R.id.rowIconBackground);
rowView.setTag(viewHolder);
//Change is here
viewHolder.mRunnable = new LoadImage(viewHolder.imgDot, position);
}else {
viewHolder = (ViewHolder) rowView.getTag();
//Change is here
myHandler.removeCallbacks(viewHolder.mRunnable);
}
//Start Custom Image View///////
String photoUrl1 = arrayList.get(position).getPhotoUrl();
if (photoUrl1.length()<8){
photoUrl1 = "SOME_URL";
}
final String photoUrl = photoUrl1;
final ImageView imgDot = viewHolder.imgDot;
// final viewHolder.imgDot = (ImageView) rowView.findViewById(R.id.rowIcon);
final View finalRowView = rowView;
final ViewHolder finalViewHolder = viewHolder;
//Change is here
myHandler.postDelayed(viewHolder.mRunnable, 3000);
return rowView;
}
I want to achieve this screenshot like design with Horizontal scroll view.
I already done with the Horizontal scroll view with the help of Wheel view library
https://github.com/chemalarrea/Android-wheel
But I am not getting any idea about how to fill a color in this images without disturbing image square area using setBackground method for Imageview.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="15dp">
<kankan.wheel.widget.WheelView
android:id="#+id/slotwheel_look_color"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Adapter
private class SlotMachineAdapter_Look extends AbstractWheelAdapter {
// Image size
final int IMAGE_WIDTH = 100;
final int IMAGE_HEIGHT = 100;
private LayoutInflater mInflater;
private LinearLayout mLn_parant;
private ImageView mImg_condition;
// Layout inflater
private Context context;
// Slot machine symbols
private final int items[] = new int[]{
R.drawable.image_1,
R.drawable.image_2,
R.drawable.image_3,
R.drawable.image_4,
R.drawable.image_5,
R.drawable.image_6,
R.drawable.image_7,
R.drawable.image_8,
R.drawable.image_9
};
// Cached images
private List<SoftReference<Bitmap>> images;
/**
* Constructor
*/
public SlotMachineAdapter_Look(Context context) {
this.context = context;
mInflater = LayoutInflater.from(context);
images = new ArrayList<SoftReference<Bitmap>>(items.length);
for (int id : items) {
images.add(new SoftReference<Bitmap>(loadImage(id)));
}
}
/**
* Loads image from resources
*/
private Bitmap loadImage(int id) {
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), id);
Bitmap scaled = Bitmap.createScaledBitmap(bitmap, IMAGE_WIDTH, IMAGE_HEIGHT, true);
bitmap.recycle();
return scaled;
}
#Override
public int getItemsCount() {
return items.length;
}
// Layout params for image view
LayoutParams params = new LayoutParams(IMAGE_WIDTH, IMAGE_HEIGHT);
#Override
public View getItem(int index, View cachedView, ViewGroup parent) {
ImageView img;
if (cachedView != null) {
img = (ImageView) cachedView;
} else {
img = new ImageView(context);
}
img.setLayoutParams(params);
SoftReference<Bitmap> bitmapRef = images.get(index);
Bitmap bitmap = bitmapRef.get();
if (bitmap == null) {
bitmap = loadImage(items[index]);
images.set(index, new SoftReference<Bitmap>(bitmap));
}
BitmapDrawable ob = new BitmapDrawable(getResources(), bitmap);
img.setBackground(ob);
img.setImageBitmap(bitmap);
img.setColorFilter(Color.YELLOW);
return img;
// return view;
}
}
Please help me out for this issue.
Thanks in advance
Used the setColorFilter
Drawable myIcon = getResources().getDrawable( R.drawable.myicon);
ColorFilter filter = new LightingColorFilter( Color.BLUE, Color.BLUE );
myIcon.setColorFilter(filter);
Imageview.setImageDrawable(myIcon);
Or
Resources res = context.getResources();
final ImageView image = (ImageView) findViewById(R.id.image);
final int newColor = res.getColor(R.color.new_color);
image.setColorFilter(newColor, Mode.SRC_ATOP);
I used a ListView which contains a ImageView and a TextView. I want to get a image from server. I debug the code below, which told me that I can get the image successful, but when return, the image disappeared. I don't know why. I am the new begginner of android. Hope anyone can help me.
The ListView Adapter class:
public View getView(int position, View convertView, ViewGroup parent) {
News news = getItem(position);
View view = LayoutInflater.from(getContext()).inflate(resourceId, null);
newsImage = (ImageView) view.findViewById(R.id.news_image);
newsTitle = (TextView) view.findViewById(R.id.news_title);
newsTitle.setText(news.getTitle());
bitmap = HttpUtil.sendImageRequest(news.getImageUrl());
newsImage.setImageBitmap(ImageUtility.ImageSolution(bitmap, newsImage));
return view;
}
the sendImageRequest method:
public static Bitmap sendImageRequest(final String address){
final Bitmap[] bitmap = new Bitmap[1];
new Thread(new Runnable() {
#Override
public void run() {
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(address).openConnection();
connection.setRequestMethod("GET");
connection.setDoInput(true);
InputStream in = connection.getInputStream();
bitmap[0] = BitmapFactory.decodeStream(in);
} catch (java.io.IOException e) {
e.printStackTrace();
} finally {
if (connection != null){
connection.disconnect();
}
}
}
}).start();
return bitmap[0];
}
the ImageSolution method:
public static Bitmap ImageSolution (Bitmap bitmap, ImageView imageView){
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int newWidth = imageView.getWidth();
int newHeight = imageView.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width,
height, matrix, true);
return resizedBitmap;
}
the address is http://p2.zhimg.com/10/7b/107bb4894b46d75a892da6fa80ef504a.jpg.
Thank you so much.
You can use a third party library named Glide , which is recommended by google . To add this library , add the the following dependency in your build.gradle file , in module app .
dependencies {
compile 'com.github.bumptech.glide:glide:3.5.2'
compile 'com.android.support:support-v4:22.0.0'
}
And then you can simply load image in following way
Glide.with(context)
.load(news.getImageUrl())
.into(newsImage);
bitmap = HttpUtil.sendImageRequest(news.getImageUrl());
bitmap will always be empty as it is an image request. The function starts a thread but returns immediately. So returns an empty bitmap.
newsImage.setImageBitmap(ImageUtility.ImageSolution(bitmap, newsImage));
If you then try to set that empty bitmap to an imageview things go wrong.
Redesign your app. Only when the thread finishes there is a valid bitmap. And then you can use it.
Why don't you use the Picasso library?
It's really easy to use
Picasso.with(context).load(news.getImageUrl()).into(newsImage);
And it provides caching and image transformations.
Make a viewHolder class inside adapter class,
private static class ViewHolder {
public TextView newsTitle = null;
public ImageView newsImage = null;
}
then code your getView like,
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder itemHolder;
View view = convertView;
if (view == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
itemHolder = new ViewHolder();
view = inflater.inflate(layoutResID, parent, false);
itemHolder.newsImage = (ImageView) view.findViewById(R.id.news_image);
itemHolder.newsTitle = (TextView) view.findViewById(R.id.news_title);
view.setTag(itemHolder);
} else {
itemHolder = (viewHolder) view.getTag();
}
News news = getItem(position);
itemHolder.newsTitle.setText(news.getTitle());
bitmap = HttpUtil.sendImageRequest(news.getImageUrl());
itemHolder.newsImage.setImageBitmap(ImageUtility.ImageSolution(bitmap, newsImage));
return view;
}
or, you can use picasso, it is easy to use...
add this line inside dependencies,
compile 'com.squareup.picasso:picasso:2.5.0'
and for loading image code for loading image will be,
Picasso.with(context).load(news.getImageUrl()).into(itemHolder.newsImage);
I would like to show the custom marker to google map and cluster them. The marker contains a ImageView that will shows the avatar that is downloaded from network. Here is my target:
Everythings are OK, however, when I implemented the Google Maps Android Marker Clustering Utility, the ImageView shows the same avatar (sometime two wrong avatars).
Here is my custom MarkerRender:
public class MarkerRender extends DefaultClusterRenderer<Image> {
private static final String TAG = MarkerRender.class.getSimpleName();
private IconGenerator clusterGenerator;
private IconGenerator markerGenerator;
private ImageView mImgMarkerThumbnail;
private ImageView mImgMarkerClusterThumbnail;
private TextView txtSizeCluster;
private Activity activity;
private Bitmap mask, background;
private AtomicInteger imageDownloadCounter;
private int totalItem;
private ImageSize imageSize;
public MarkerRender(FragmentActivity activity, GoogleMap mMap, ClusterManager<Image> mClusterManager) {
super(activity, mMap, mClusterManager);
this.activity = activity;
imageDownloadCounter = new AtomicInteger(0);
mask = BitmapFactory.decodeResource(activity.getResources(),
R.drawable.annotation_behind);
background = BitmapFactory.decodeResource(activity.getResources(),
R.drawable.annotation_behind);
setUpClusterIcon();
setUpMarker();
}
private void setUpClusterIcon() {
clusterGenerator = new IconGenerator(activity);
View clusterView = activity.getLayoutInflater().inflate(R.layout.custom_marker_cluster, null);
txtSizeCluster = (TextView) clusterView.findViewById(R.id.tv_number_marker);
mImgMarkerClusterThumbnail = (ImageView) clusterView.findViewById(R.id.img_load);
clusterGenerator.setContentView(clusterView);
clusterGenerator.setBackground(null);
}
private void setUpMarker() {
markerGenerator = new IconGenerator(activity);
View markerView = activity.getLayoutInflater().inflate(R.layout.custom_marker, null);
mImgMarkerThumbnail = (ImageView) markerView.findViewById(R.id.img_load);
markerGenerator.setContentView(markerView);
markerGenerator.setBackground(null);
}
#Override
protected void onBeforeClusterItemRendered(final Image image, final MarkerOptions markerOptions) {
initImageSizeIfNeed();
Bitmap icon = markerGenerator.makeIcon();
PFLogManager.INSTANCE.logE(TAG, "maken icon: " + icon.hashCode());
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
icon.recycle();
}
#Override
protected void onClusterItemRendered(final Image image, Marker marker) {
super.onClusterItemRendered(image, marker);
ImageLoader.getInstance().loadImage(image.getMapImageLink(), imageSize,
new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
Bitmap croppedBitmap = Helpers.makeCroppedBitmap(loadedImage, background, mask);
mImgMarkerThumbnail.setImageBitmap(croppedBitmap);
}
});
}
#Override
protected void onBeforeClusterRendered(Cluster<Image> cluster, MarkerOptions markerOptions) {
initImageSizeIfNeed();
Bitmap icon = clusterGenerator.makeIcon();
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
icon.recycle();
}
#Override
protected void onClusterRendered(Cluster<Image> cluster, Marker marker) {
super.onClusterRendered(cluster, marker);
ArrayList<Image> list = new ArrayList<>(cluster.getItems());
setTextNumberMarker(cluster);
String urlFirstImage = list.get(0).getMapImageLink();
ImageLoader.getInstance().loadImage(urlFirstImage, imageSize,
new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
final Bitmap croppedBitmap = Helpers.makeCroppedBitmap(loadedImage, background, mask);
mImgMarkerClusterThumbnail.setImageBitmap(croppedBitmap);
}
});
}
private void loadClusterThumbnail(String url) {
}
private void setTextNumberMarker(Cluster<Image> cluster) {
int size = cluster.getSize();
if (size > 99) {
txtSizeCluster.setText("99+");
} else {
txtSizeCluster.setText(String.valueOf(cluster.getSize()));
}
}
#Override
protected boolean shouldRenderAsCluster(Cluster cluster) {
return cluster.getSize() > 1;
}
}
I've guess that the issue is I use only one ImageView to show those avatar, so I try to use unique ImageView for each marker (by inflat new one from xml every time needed), but the result is they are all show the blank marker (just the background and there is no avatar).
I've resolved it myself. My solution is use the Marker.setIcon() method after the image is downloaded from netword or got from cache. I dont use the ImageView anymore.
So, i modified the above MarkerRender class:
The setUpClusterIcon() method:
private void setUpClusterIcon() {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(markerWidth, markerHeight);
ImageView marker = new ImageView(activity);
marker.setLayoutParams(params);
clusterGenerator = new IconGenerator(activity);
clusterGenerator.setContentView(marker);
clusterGenerator.setBackground(null);
}
And the onClusterItemRendered() method:
protected void onClusterItemRendered(final Image image, final Marker marker) {
super.onClusterItemRendered(image, marker);
ImageLoader.getInstance().loadImage(image.getMapImageLink(), imageSize,
new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
Bitmap croppedBitmap = Helpers.makeClusterItemBitmap(background, loadedImage, mask);
try {
marker.setIcon(BitmapDescriptorFactory.fromBitmap(croppedBitmap));
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
Also the makeClusterItemBitmap helper method:
public static Bitmap makeClusterItemBitmap(Bitmap background, Bitmap original, Bitmap mask) {
Bitmap croppedOriginal = makeCroppedBitmap(original, mask);
Bitmap result = Bitmap.createBitmap(background.getWidth(), background.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
croppedOriginal = Bitmap.createScaledBitmap(croppedOriginal, croppedOriginal.getWidth() - 20, croppedOriginal.getHeight() - 20, true);
mCanvas.drawBitmap(background, 0, 0, null);
mCanvas.drawBitmap(croppedOriginal, 10, 10, null);
return result;
}
public static Bitmap makeCroppedBitmap(Bitmap original, Bitmap mask) {
original = Bitmap.createScaledBitmap(original, mask.getWidth(),
mask.getHeight(), true);
Bitmap result = Bitmap.createBitmap(original.getWidth(), original.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(original, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
return result;
}
Done, finish three nightmare researchingdays days :P
However, this approach leads new issue: the performance. Cause by drawing new bitmap with many layers, the map is laggy a bit. I'm thinking in improving this :)
Any sugguestion are appriciate :D
I have set up a gallery for my app using BaseAdapter. Here is the code I used for the gallery.
homeGallery = (Gallery) findViewById(R.id.homeimggallery);
homeGallery.setSpacing(0);
homeGallery.setSelection(0);
homeGallery.setAdapter(new AddImgAdp(this));
private class AddImgAdp extends BaseAdapter {
private int GalItemBg, temp;
private Context cont;
private View convertView1;
private ViewGroup parent1;
private Bitmap mask = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.mask);
private Bitmap whiteBorder = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.stroke);
private Bitmap blueBorder = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.strokeactive);
private Bitmap src;
private Bitmap dest;
private Canvas canvas;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private ImageView homeImgView;
private ImageView[] homeImgViewArr= new ImageView[arrThumbImage.length];
public AddImgAdp(Context c) {
cont = c;
TypedArray typArray = obtainStyledAttributes(styleable.GalleryTheme);
GalItemBg = typArray.getResourceId(styleable.GalleryTheme_android_galleryItemBackground, 0);
typArray.recycle();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
}
public int getCount() {
return arrThumbImage.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
homeImgView = new ImageView(cont);
try{
src = BitmapFactory.decodeResource(mContext.getResources(), arrThumbImage[position]);
dest = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(dest);
canvas.drawColor(Color.TRANSPARENT);
canvas.save();
canvas.translate((canvas.getWidth() - src.getWidth())>> 1, (canvas.getHeight() - src.getHeight())>> 1);
canvas.drawBitmap(src, 0, 0, null);
canvas.drawBitmap(mask, 0, 0, paint);
canvas.drawBitmap(dest, 0, 0, paint);
homeImgView.setBackgroundDrawable(new BitmapDrawable(dest));
homeImgView.setImageResource(R.drawable.stroke);
homeImgView.setScaleType(ImageView.ScaleType.FIT_XY);
homeImgViewArr[position] = homeImgView;
} catch(Exception e) {}
return homeImgView;
}
}
The gallery looks like below:
On finger movement, it is moving right to left or left to right as expected. Now I want to add some onClick action to items. If user click on any image, it will be selected and align in the middle. The following code is used for this action.
homeGallery.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
homeGallery.setSelection(position);
}
});
But it results wrongly. If I am selecting item no. 2, the item no. 3 got selected, although setSelection action is firing against item no 2. If I click on the right most item of the above pic, it is resulting line below:
What is the problem in my code?
I'm working with a Gallery myself, but I'm not quite sure what the problem is here, since your code is further than where I stand.
Anyways, since you click item 3?? and you get item 4 centered I can think of a few options:
-Something is wrong with the array indexes, might wanna take a log of the positions.
-Personally, I work with an array of Integer and on the getView() I just get the position which is easier than what you're doing I believe.
public ArrayList mImageIds = new ArrayList(); the array...
i.setImageResource(mImageIds.get(position)); and in getView() it's sorted.
Hope this is helpful