I have a recycle view to show all photo thumbnail items. When click on item, I use transition for imageview in this item to Detail activity. The problem is that image source is gotten from internet by UIL. And sometime (not always) the images not reload correct size like this:
// on view holder item click
final Pair<View, String>[] pairs = TransitionHelper.createSafeTransitionParticipants(this, false,
new Pair<>(((ItemViewHolder) viewHolder).thumbnail, getString(R.string.TransitionName_Profile_Image)),
new Pair<>(((ItemViewHolder) viewHolder).tvName, getString(R.string.TransitionName_Profile_Name)));
ActivityOptionsCompat transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(this, pairs);
startActivityForResult(intent, requestCode, transitionActivityOptions.toBundle());
Detail activity
// try to post pone transition until UIL load finish
ActivityCompat.postponeEnterTransition(this);
getSupportFragmentManager().beginTransaction().replace(R.id.layoutContent, new DetailFragment()).commit();
Fragment Detail
ImageLoader.getInstance().displayImage(url, imageViewDetail, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
finishAnimation();
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
finishAnimation();
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
finishAnimation();
}
});
private void finishAnimation(){
ActivityCompat.startPostponedEnterTransition(getActivity());
imageViewDetail.invalidate();
}
fragment_detail.xml
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:transitionName="#string/TransitionName.Profile.Image"
android:id="#+id/imageViewDetail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"/>
</FrameLayout>
I even wait views are laid out before load image but still not work:
imageViewDetail.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
// code load image from UIL
return false;
}
});
Is there any way to avoid this issue?
this xml can handle diferent image size
<ScrollView
android:id="#+id/vScroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="51dp"
android:scrollbars="none" >
<HorizontalScrollView
android:id="#+id/hScroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none"
android:layout_gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/imgFullscreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY" />
</LinearLayout>
</HorizontalScrollView>
</ScrollView>
in java
fullImageView = (ImageView) findViewById(R.id.imgFullscreen);
selectedPhoto = (FeedItem) i.getSerializableExtra(TAG_SEL_IMAGE);
zoom = 1;
if (selectedPhoto != null) {
fetchFullResolutionImage();
} else {
Toast.makeText(getApplicationContext(),
getString(R.string.msg_unknown_error), Toast.LENGTH_SHORT)
.show();
}
private void fetchFullResolutionImage() {
try {
final URL url = new URL(selectedPhoto.getImge());
new Thread(new Runnable() {
#Override
public void run() {
try {
Bitmap bmp = BitmapFactory.decodeStream(url
.openStream());
if (bmp != null)
setImage(bmp);
else {
showToast("Error fetching image!");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
private void setImage(final Bitmap bmp) {
runOnUiThread(new Runnable() {
public void run() {
fullImageView.setImageBitmap(bmp);
adjustImageAspect(selectedPhoto.getWidth(),
selectedPhoto.getHeight());
}
});
}
private void adjustImageAspect(int bWidth, int bHeight) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
if (bWidth == 0 || bHeight == 0)
return;
int swidth;
if (android.os.Build.VERSION.SDK_INT >= 13) {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
swidth = size.x;
} else {
Display display = getWindowManager().getDefaultDisplay();
swidth = display.getWidth();
}
int new_height = 0;
new_height = swidth * bHeight / bWidth;
params.width = swidth;
params.height = new_height;
saveW = swidth;
saveH = new_height;
fullImageView.setLayoutParams(params);
}
Related
Can anyone please suggest how to implement the following in my droid app?
I've created a custom gallery, and when an image is selected, I show a preview of the image exactly like instagram. Now when I scoll up, I need some 20% of the image view to stick to the top like this:
I'm right now using, Observablegrid view, which is of not that much use!
Please suggest any ideas. Thanks!
Here is my answer using the same Observablegridview, which got to work after some analysis and modifications while scrolling the grid.
For the grid of image to be displayed, use this ObservableGridView.java
Here is the xml layout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/mainFrame">
<com.sampleapp.Observablescroll.ObservableGridView
android:id="#+id/camera_gridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:numColumns="4" />
<RelativeLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/gallery_lay"
android:layout_width="wrap_content"
android:layout_height="365dp"
android:background="#color/black"
android:orientation="vertical">
<com.fenchtose.nocropper.CropperImageView
android:id="#+id/gallery_click_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:scaleType="centerCrop"
app:grid_color="#color/action_bar_color" />
</RelativeLayout>
<View
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="300dp" />
</RelativeLayout>
</FrameLayout>
In your java class, implement ObservableScrollViewCallbacks
mHeaderView = (RelativeLayout) rootview.findViewById(R.id.header);
mToolbarView = rootview.findViewById(R.id.toolbar);
camera_gridView = (ObservableGridView) rootview.findViewById(R.id.camera_gridView);
LayoutInflater inflaters = LayoutInflater.from(getActivity());
camera_gridView.addHeaderView(inflaters.inflate(R.layout.image_holder_view, camera_gridView, false));
// view that leaves 300dp space to display the selected image from the grid
camera_gridView.addHeaderView(inflaters.inflate(R.layout.sticky_tool_bar_view, camera_gridView, false));
// a sticky view with action bar's height, so that the grid doesn't scroll above this
camera_gridView.setScrollViewCallbacks(this);
//overridden methods
#Override
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
if (dragging) {
int toolbarHeight = mToolbarView.getHeight();
// int toolbarHeight = 300;
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
if (firstScroll) {
float currentHeaderTranslationY = ViewHelper.getTranslationY(mHeaderView);
if (-toolbarHeight < currentHeaderTranslationY) {
mBaseTranslationY = scrollY;
}
}
float headerTranslationY = ScrollUtils.getFloat(-(scrollY - mBaseTranslationY), -toolbarHeight, 0);
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewHelper.setTranslationY(mHeaderView, headerTranslationY);
}
}
#Override
public void onDownMotionEvent() {
}
#Override
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
mBaseTranslationY = 0;
if (scrollState == ScrollState.DOWN) {
int toolbarHeight = mToolbarView.getHeight();
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
int scrollY = camera_gridView.getCurrentScrollY();
if (toolbarHeight <= scrollY) {
hideToolbar();
} else {
showToolbar();
}
} else if (scrollState == ScrollState.UP) {
int toolbarHeight = mToolbarView.getHeight();
int scrollY = camera_gridView.getCurrentScrollY();
if (toolbarHeight <= scrollY) {
System.out.println("++++upif" + scrollY);
hideToolbar();
} else {
System.out.println("++++upelse" + scrollY);
showToolbar();
}
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
} else {
if (!toolbarIsShown() && !toolbarIsHidden()) {
showToolbar();
}
}
}
//method to show the toolbar
private void showToolbar() {
float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
if (headerTranslationY != 0) {
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewPropertyAnimator.animate(mHeaderView).translationY(0).setDuration(200).start();
}
}
//method to hide the toolbar
private void hideToolbar() {
float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
int toolbarHeight = mToolbarView.getHeight();
if (headerTranslationY != -toolbarHeight) {
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewPropertyAnimator.animate(mHeaderView).translationY(-toolbarHeight).setDuration(200).start();
}
}
private boolean toolbarIsShown() {
return ViewHelper.getTranslationY(mHeaderView) == 0;
}
private boolean toolbarIsHidden() {
return ViewHelper.getTranslationY(mHeaderView) == -mToolbarView.getHeight();
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_below="#+id/mainFrame">
<RelativeLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/gallery_lay"
android:layout_width="wrap_content"
android:layout_height="365dp"
android:background="#color/black"
android:orientation="vertical">
<com.fenchtose.nocropper.CropperView
android:id="#+id/imageview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff282828"
app:nocropper__grid_color="#color/colorAccent"
app:nocropper__grid_opacity="0.8"
app:nocropper__grid_thickness="0.8dp"
app:nocropper__padding_color="#color/colorAccent" />
</RelativeLayout>
</RelativeLayout>
<com.myapp.Util.ObservableGridView
android:id="#+id/camera_gridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:numColumns="4" />
</FrameLayout>
And below is java implementation
public class GalleryFragmentTest2 extends Fragment implements View.OnClickListener, ImageGridItemListner, ObservableScrollViewCallbacks {
private static final String TAG = "GalleryFragment";
CropperView mImageView;
RecyclerView recImgHolder;
CoordinatorLayout container;
AppBarLayout app_bar_main;
private Bitmap originalBitmap;
private Bitmap mBitmap;
private boolean isSnappedToCenter = false;
private int rotationCount = 0;
//constants
private static final int NUM_GRID_COLUMNS = 4;
//widgets
private GridView gridView;
private ImageView galleryImage;
private Spinner directorySpinner;
//vars
private ArrayList<Model_images> directories;
private String mAppend = "file://";
private String mSelectedImage;
RelativeLayout mHeaderView, relCropperView;
ObservableGridView camera_gridView;
private int mBaseTranslationY;
private void initImageLoader() {
UniversalImageLoader universalImageLoader = new UniversalImageLoader(getContext());
ImageLoader.getInstance().init(universalImageLoader.getConfig());
}
#SuppressLint("ClickableViewAccessibility")
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.gallery_test2, container, false);
mHeaderView = (RelativeLayout) view.findViewById(R.id.header);
View mToolbarView = view.findViewById(R.id.toolbar);
camera_gridView = (ObservableGridView) view.findViewById(R.id.camera_gridView);
LayoutInflater inflaters = LayoutInflater.from(getActivity());
View view1 = inflaters.inflate(R.layout.snippet_top_gallerytoolbar,camera_gridView,false);
View view2 = inflaters.inflate(R.layout.rec_img_test,camera_gridView,false);
camera_gridView.addHeaderView(inflaters.inflate(R.layout.snippet_top_gallerytoolbar,camera_gridView,false));
// view that leaves 300dp space to display the selected image from the grid
camera_gridView.addHeaderView(inflaters.inflate(R.layout.rec_img_test,camera_gridView,false));
// a sticky view with action bar's height, so that the grid doesn't scroll above this
camera_gridView.setScrollViewCallbacks(this);
mImageView = (CropperView) view.findViewById(R.id.imageview);
recImgHolder = view2.findViewById(R.id.recImgHolder);
LinearLayoutManager manager = new GridLayoutManager(getActivity(), 4);
recImgHolder.setLayoutManager(manager);
recImgHolder.setHasFixedSize(true);
recImgHolder.setItemViewCacheSize(20);
recImgHolder.setDrawingCacheEnabled(true);
recImgHolder.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
TextView nextScreen = (TextView) view.findViewById(R.id.tvNext);
directorySpinner = (Spinner) view1.findViewById(R.id.spinnerDirectory);
directories = new ArrayList<>();
Log.d(TAG, "onCreateView: started.");
initImageLoader();
init();
mImageView.setDebug(true);
mImageView.setGestureEnabled(true);
mImageView.setGridCallback(new CropperView.GridCallback() {
#Override
public boolean onGestureStarted() {
return true;
}
#Override
public boolean onGestureCompleted() {
return false;
}
});
return view;
}
private void init() {
try {
FilePaths filePaths = new FilePaths();
directories = new ArrayList<>();
//check for other folders indide "/storage/emulated/0/pictures"
directories = FileSearch.fn_imagespath(Objects.requireNonNull(getContext()), filePaths.PICTURES);
ArrayList<String> directoryNames = new ArrayList<>();
for (int i = 0; i < directories.size(); i++) {
int index = directories.get(i).getStr_folder().lastIndexOf("/");
String string = directories.get(i).getStr_folder().substring(index + 1);
directoryNames.add(string);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_spinner_item, directoryNames);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
directorySpinner.setAdapter(adapter);
directorySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG, "onItemClick: selected: " + directories.get(position));
//setup our image grid for the directory chosen
setupGridView(directories.get(position));
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}catch (Exception e){
e.printStackTrace();
}
}
private void setupGridView(Model_images selectedDirectory) {
try {
final ArrayList<String> imgURLs = selectedDirectory.getAl_imagepath();
//use the grid adapter to adapter the images to gridview
GridImageAdapter adapter = new GridImageAdapter(getActivity(), R.layout.layout_grid_imageview, mAppend, imgURLs, (ImageGridItemListner) this);
adapter.setGridItemListner(this);
recImgHolder.setAdapter(adapter);
//set the first image to be displayed when the activity fragment view is inflated
try {
setImage(imgURLs.get(0), mAppend);
} catch (ArrayIndexOutOfBoundsException e) {
Log.e(TAG, "setupGridView: ArrayIndexOutOfBoundsException: " + e.getMessage());
}
}catch (Exception e){
e.printStackTrace();
Toast.makeText(getActivity(), ""+e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void setImage(String imgURL, String append) {
Log.d(TAG, "setImage: setting image");
ImageLoader imageLoader = ImageLoader.getInstance();
Bitmap bmp = imageLoader.loadImageSync(append + imgURL);
mImageView.setImageBitmap(bmp);
mBitmap = bmp;
originalBitmap = bmp;
}
private void rotateImage() {
if (mBitmap == null) {
Log.e(TAG, "bitmap is not loaded yet");
return;
}
mBitmap = BitmapUtils.rotateBitmap(mBitmap, 90);
mImageView.setImageBitmap(mBitmap);
rotationCount++;
}
private void snapImage() {
if (isSnappedToCenter) {
mImageView.cropToCenter();
} else {
mImageView.fitToCenter();
}
isSnappedToCenter = !isSnappedToCenter;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.rotate_button:
rotateImage();
break;
case R.id.snap_button:
snapImage();
break;
}
}
#Override
public void onImageGridItemClick(String imgURL) {
try {
setImage(imgURL, mAppend);
} catch (ArrayIndexOutOfBoundsException e) {
Log.e(TAG, "setupGridView: ArrayIndexOutOfBoundsException: " + e.getMessage());
}
}
//overridden methods
#Override
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
if (dragging) {
int toolbarHeight = mHeaderView.getHeight();
// int toolbarHeight = 300;
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
if (firstScroll) {
float currentHeaderTranslationY = ViewHelper.getTranslationY(mHeaderView);
if (-toolbarHeight < currentHeaderTranslationY) {
mBaseTranslationY = scrollY;
}
}
float headerTranslationY = ScrollUtils.getFloat(-(scrollY - mBaseTranslationY), -toolbarHeight, 0);
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewHelper.setTranslationY(mHeaderView, headerTranslationY);
}
}
#Override
public void onDownMotionEvent() {
}
#Override
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
mBaseTranslationY = 0;
if (scrollState == ScrollState.DOWN) {
int toolbarHeight = mHeaderView.getHeight();
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
int scrollY = camera_gridView.getCurrentScrollY();
if (toolbarHeight <= scrollY) {
hideToolbar();
} else {
showToolbar();
}
} else if (scrollState == ScrollState.UP) {
int toolbarHeight = mHeaderView.getHeight();
int scrollY = camera_gridView.getCurrentScrollY();
if (toolbarHeight <= scrollY) {
System.out.println("++++upif" + scrollY);
hideToolbar();
} else {
System.out.println("++++upelse" + scrollY);
showToolbar();
}
if (camera_gridView.getCurrentScrollY() == 0) {
showToolbar();
}
} else {
if (!toolbarIsShown() && !toolbarIsHidden()) {
showToolbar();
}
}
}
//method to show the toolbar
private void showToolbar() {
float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
if (headerTranslationY != 0) {
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewPropertyAnimator.animate(mHeaderView).translationY(0).setDuration(200).start();
}
}
//method to hide the toolbar
private void hideToolbar() {
float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
int toolbarHeight = mHeaderView.getHeight();
if (headerTranslationY != -toolbarHeight) {
ViewPropertyAnimator.animate(mHeaderView).cancel();
ViewPropertyAnimator.animate(mHeaderView).translationY(-toolbarHeight).setDuration(200).start();
}
}
private boolean toolbarIsShown() {
return ViewHelper.getTranslationY(mHeaderView) == 0;
}
private boolean toolbarIsHidden() {
return ViewHelper.getTranslationY(mHeaderView) == -mHeaderView.getHeight();
}
}
inflated headerview in observable is
layout :- snippet_top_gallerytoolbar
<android.support.design.widget.AppBarLayout android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/colorPrimary"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.Toolbar
android:id="#+id/profileToolBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/ivCloseShare"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:layout_marginEnd="20dp"
android:src="#drawable/ic_back" />
<Spinner
android:id="#+id/spinnerDirectory"
android:layout_width="#dimen/_120sdp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/ivCloseShare"
android:gravity="center_vertical"
android:text="Gallery"
android:textColor="#color/black"
android:textSize="20sp">
</Spinner>
<TextView
android:id="#+id/tvNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
android:text="#string/string_next"
android:textColor="#color/white"
android:textSize="20sp" />
</RelativeLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
second added headerview to observablegrid
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recImgHolder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
i am getting view like below
I'm really new at this and I'm trying to load profile pics from gallery and camera into ImageButton. I'm able to add image from gallery but the image does not fit completely into the ImageButton. Some space still gets left out from the imagebutton. I want the image to automatically fit into imagebutton.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.sam.sport.MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/LL1" >
<LinearLayout
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp" >
<ImageButton
android:id="#+id/profile_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/ic_launcher"
android:scaleType="fitXY"
android:adjustViewBounds="true" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Activity class is as below:-
public class MainActivity extends Activity {
ImageButton ib;
private static Bitmap Image = null;
private static final int GALLERY = 1;
private static Bitmap rotateImage = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ib = (ImageButton)findViewById(R.id.profile_pic);
ib.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
ib.setImageBitmap(null);
if (Image != null)
Image.recycle();
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), GALLERY);
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == GALLERY && resultCode != 0) {
Uri mImageUri = data.getData();
try {
Image = Media.getBitmap(this.getContentResolver(), mImageUri);
if (getOrientation(getApplicationContext(), mImageUri) != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(getOrientation(getApplicationContext(), mImageUri));
if (rotateImage != null)
rotateImage.recycle();
rotateImage = Bitmap.createBitmap(Image, 0, 0, Image.getWidth(), Image.getHeight(), matrix,
true);
ib.setImageBitmap(rotateImage);
} else
ib.setImageBitmap(Image);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
}
Convert it to Drawable then use setBackgroundDrawable insted of setImageBitmap
Drawable drawable = new BitmapDrawable(rotateImage);
ib.setBackgroundDrawable(drawable);
Use below line of code for re-sizing your bitmap
Bitmap BITMAP_IMAGE = Bitmap.createBitmap(IMAGE_VIEW.getWidth(),IMAGE_VIEW.getHeight(), Bitmap.Config.RGB_565);
Bitmap resizedBitmap = Bitmap.createScaledBitmap(BITMAP_IMAGE, 100, 100, false); ////Here BITMAP_IMAGE is your bitmap which you want to resize
Get the imageButton height and width
Bitmap bitmapScaled = Bitmap.createScaledBitmap(Image, ib_width, ib_height, true);
Drawable drawable = new BitmapDrawable(bitmapScaled);
ib.setBackgroundDrawable(drawable);
Keep in mind about OOM exception.
To get imageButton height and width look into this and this
I've got the perfect solution. To resize imageview I used the below code as provided in the [Android ImageView adjusting parent's height and fitting width
public class ResizableImageView extends ImageView {
public ResizableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
Drawable d = getDrawable();
if(d!=null){
// ceil not round - avoid thin vertical gaps along the left/right edges
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
setMeasuredDimension(width, height);
}else{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
]1
I'm trying to upload an Image from my API to show it as profile picture, the problem is from the first time that the user opens the navdrawer the image doesn't load and it makes the entire layout disappear, but from the second time it all works, and I notice that it happens when the width of the image is less than the height. This is the class that I'm using:
public class CircledNetworkImageView extends ImageView {
public boolean mCircled;
/**
* The URL of the network image to load
*/
private String mUrl;
/**
* Resource ID of the image to be used as a placeholder until the network image is loaded.
*/
private int mDefaultImageId;
/**
* Resource ID of the image to be used if the network response fails.
*/
private int mErrorImageId;
/**
* Local copy of the ImageLoader.
*/
private ImageLoader mImageLoader;
/**
* Current ImageContainer. (either in-flight or finished)
*/
private ImageLoader.ImageContainer mImageContainer;
public CircledNetworkImageView(Context context) {
this(context, null);
}
public CircledNetworkImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircledNetworkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* Sets URL of the image that should be loaded into this view. Note that calling this will
* immediately either set the cached image (if available) or the default image specified by
* {#link CircledNetworkImageView#setDefaultImageResId(int)} on the view.
* <p/>
* NOTE: If applicable, {#link CircledNetworkImageView#setDefaultImageResId(int)} and
* {#link CircledNetworkImageView#setErrorImageResId(int)} should be called prior to calling
* this function.
*
* #param url The URL that should be loaded into this ImageView.
* #param imageLoader ImageLoader that will be used to make the request.
*/
public void setImageUrl(String url, ImageLoader imageLoader) {
mUrl = url;
mImageLoader = imageLoader;
// The URL has potentially changed. See if we need to load it.
loadImageIfNecessary(false);
}
/**
* Sets the default image resource ID to be used for this view until the attempt to load it
* completes.
*/
public void setDefaultImageResId(int defaultImage) {
mDefaultImageId = defaultImage;
}
/**
* Sets the error image resource ID to be used for this view in the event that the image
* requested fails to load.
*/
public void setErrorImageResId(int errorImage) {
mErrorImageId = errorImage;
}
/**
* Loads the image for the view if it isn't already loaded.
*
* #param isInLayoutPass True if this was invoked from a layout pass, false otherwise.
*/
void loadImageIfNecessary(final boolean isInLayoutPass) {
int width = getWidth();
int height = getHeight();
ScaleType scaleType = getScaleType();
boolean wrapWidth = false, wrapHeight = false;
if (getLayoutParams() != null) {
wrapWidth = getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT;
wrapHeight = getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT;
}
// if the view's bounds aren't known yet, and this is not a wrap-content/wrap-content
// view, hold off on loading the image.
boolean isFullyWrapContent = wrapWidth && wrapHeight;
if (width == 0 && height == 0 && !isFullyWrapContent) {
return;
}
// if the URL to be loaded in this view is empty, cancel any old requests and clear the
// currently loaded image.
if (TextUtils.isEmpty(mUrl)) {
if (mImageContainer != null) {
mImageContainer.cancelRequest();
mImageContainer = null;
}
setDefaultImageOrNull();
return;
}
// if there was an old request in this view, check if it needs to be canceled.
if (mImageContainer != null && mImageContainer.getRequestUrl() != null) {
if (mImageContainer.getRequestUrl().equals(mUrl)) {
// if the request is from the same URL, return.
return;
} else {
// if there is a pre-existing request, cancel it if it's fetching a different URL.
mImageContainer.cancelRequest();
setDefaultImageOrNull();
}
}
// Calculate the max image width / height to use while ignoring WRAP_CONTENT dimens.
int maxWidth = wrapWidth ? 0 : width;
int maxHeight = wrapHeight ? 0 : height;
// The pre-existing content of this view didn't match the current URL. Load the new image
// from the network.
ImageLoader.ImageContainer newContainer = mImageLoader.get(mUrl,
new ImageLoader.ImageListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (mErrorImageId != 0) {
setImageResource(mErrorImageId);
}
}
#Override
public void onResponse(final ImageLoader.ImageContainer response, boolean isImmediate) {
// If this was an immediate response that was delivered inside of a layout
// pass do not set the image immediately as it will trigger a requestLayout
// inside of a layout. Instead, defer setting the image by posting back to
// the main thread.
if (isImmediate && isInLayoutPass) {
post(new Runnable() {
#Override
public void run() {
onResponse(response, false);
}
});
return;
}
if (response.getBitmap() != null) {
setImageBitmap(response.getBitmap());
} else if (mDefaultImageId != 0) {
setImageResource(mDefaultImageId);
}
}
}, maxWidth, maxHeight, scaleType);
// update the ImageContainer to be the new bitmap container.
mImageContainer = newContainer;
}
private void setDefaultImageOrNull() {
if (mDefaultImageId != 0) {
setImageResource(mDefaultImageId);
} else {
setImageBitmap(null);
}
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
loadImageIfNecessary(true);
}
#Override
protected void onDetachedFromWindow() {
if (mImageContainer != null) {
// If the view was bound to an image request, cancel it and clear
// out the image from the view.
mImageContainer.cancelRequest();
setImageBitmap(null);
// also clear out the container so we can reload the image if necessary.
mImageContainer = null;
}
super.onDetachedFromWindow();
}
#Override
protected void drawableStateChanged() {
super.drawableStateChanged();
invalidate();
}
/**
* In case the bitmap is manually changed, we make sure to
* circle it on the next onDraw
*/
#Override
public void setImageBitmap(Bitmap bm) {
mCircled = false;
super.setImageBitmap(bm);
}
/**
* In case the bitmap is manually changed, we make sure to
* circle it on the next onDraw
*/
#Override
public void setImageResource(int resId) {
mCircled = false;
super.setImageResource(resId);
}
/**
* In case the bitmap is manually changed, we make sure to
* circle it on the next onDraw
*/
#Override
public void setImageDrawable(Drawable drawable) {
mCircled = false;
super.setImageDrawable(drawable);
}
/**
* We want to make sure that the ImageView has the same height and width
*/
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable drawable = getDrawable();
if (drawable != null) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int diw = drawable.getIntrinsicWidth();
if (diw > 0) {
int height = width * drawable.getIntrinsicHeight() / diw;
setMeasuredDimension(width, height);
} else
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} else
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
#Override
protected void onDraw(Canvas canvas) {
//Let's circle the image
if (!mCircled && getDrawable() != null) {
Drawable d = getDrawable();
try {
//We use reflection here in case that the drawable isn't a
//BitmapDrawable but it contains a public getBitmap method.
Bitmap bitmap = (Bitmap) d.getClass().getMethod("getBitmap").invoke(d);
if (bitmap != null) {
Bitmap circleBitmap = getCircleBitmap(bitmap);
setImageBitmap(circleBitmap);
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
//Seems like the current drawable is not a BitmapDrawable or
//that is doesn't have a public getBitmap() method.
}
//Mark as circled even if it failed, because if it fails once,
//It will fail again.
mCircled = true;
}
super.onDraw(canvas);
}
/**
* Method used to circle a bitmap.
*
* #param bitmap The bitmap to circle
* #return The circled bitmap
*/
public static Bitmap getCircleBitmap(Bitmap bitmap) {
int size = Math.min(bitmap.getWidth(), bitmap.getHeight());
Bitmap output = Bitmap.createBitmap(size,
size, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
BitmapShader shader;
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,
Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
paint.setAlpha(254);
RectF rect = new RectF(0, 0, size, size);
int radius = size / 2;
canvas.drawRoundRect(rect, radius, radius, paint);
return output;
}
}
I came up with that solution, but I didn't like it, because the image loses its quality:
public class UserActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.profile_main);
toolbar = (Toolbar) findViewById(R.id.toolbar_user);
camera = (ImageView) findViewById(R.id.camera);
fechar = (TextView) findViewById(R.id.fechar);
editar = (TextView) findViewById(R.id.editar);
membro = (TextView) findViewById(R.id.membro);
nome = (TextView) findViewById(R.id.nome_usuario);
email = (TextView) findViewById(R.id.email_usuario);
email = (TextView) findViewById(R.id.email_usuario);
profilePic = (NetworkImageView) findViewById(R.id.foto);
mImageView = (ImageView) findViewById(R.id.cropped);
progress_wheel = (ProgressWheel) findViewById(R.id.progress_wheel);
camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder getImageFrom = new AlertDialog.Builder(UserActivity.this);
getImageFrom.setTitle("Abrir com:");
final CharSequence[] opsChars = {getResources().getString(R.string.takepic), getResources().getString(R.string.opengallery)};
getImageFrom.setItems(opsChars, new android.content.DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
"tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
try {
intent.putExtra("return-data", true);
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
} else if (which == 1) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_FILE);
}
dialog.dismiss();
}
});
getImageFrom.show();
}
});
profilePic.setImageUrl(GlobalModel.getPerfil().getIdDaImagem(), imageLoader);
profilePic.setDefaultImageResId(R.drawable.avatar_);
}
#Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (resultCode != RESULT_OK) return;
switch (requestCode) {
case PICK_FROM_CAMERA:
profilePic.setVisibility(View.GONE);
progress_wheel.setVisibility(View.VISIBLE);
selectedImagePath = ImageFilePath.getPath(getApplicationContext(), mImageCaptureUri);
Log.i("Image File Path", "" + selectedImagePath);
mImageCaptureUri = Uri.parse(selectedImagePath);
final BitmapFactory.Options option = new BitmapFactory.Options();
option.inSampleSize = 8;
Bitmap photo = BitmapFactory.decodeFile(mImageCaptureUri.getPath(), option);
photo = Bitmap.createScaledBitmap(photo, 200, 200, false);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + "Imagename.jpg");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
previewCapturedImage(f.getAbsolutePath());
profilePic.setVisibility(View.VISIBLE);
progress_wheel.setVisibility(View.GONE);
profilePic.setImageBitmap(BitmapFactory.decodeFile(mImageCaptureUri.getPath()));
break;
case PICK_FROM_FILE:
profilePic.setVisibility(View.GONE);
progress_wheel.setVisibility(View.VISIBLE);
mImageCaptureUri = data.getData();
selectedImagePath = ImageFilePath.getPath(getApplicationContext(), mImageCaptureUri);
Log.i("Image File Path", "" + selectedImagePath);
mImageCaptureUri = Uri.parse(selectedImagePath);
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap photoGaleria = BitmapFactory.decodeFile(mImageCaptureUri.getPath(), options);
photoGaleria = Bitmap.createScaledBitmap(photoGaleria, 200, 200, false);
ByteArrayOutputStream bytesG = new ByteArrayOutputStream();
photoGaleria.compress(Bitmap.CompressFormat.JPEG, 100, bytesG);
File fG = new File(Environment.getExternalStorageDirectory()
+ File.separator + "Imagename.jpg");
fG.createNewFile();
FileOutputStream foG = new FileOutputStream(fG);
foG.write(bytesG.toByteArray());
foG.close();
previewCapturedImage(fG.getAbsolutePath());
profilePic.setVisibility(View.VISIBLE);
progress_wheel.setVisibility(View.GONE);
profilePic.setImageBitmap(BitmapFactory.decodeFile(mImageCaptureUri.getPath()));
break;
}
} catch (Exception e)
{
e.printStackTrace();
}
}
private void previewCapturedImage(String path) {
try {
UploadFoto mUpload = new UploadFoto(path);
mUpload.setEventoListener(new IExecutarTarefa<UploadFoto>() {
#Override
public void AntesDeExecutar(UploadFoto tarefa) {
}
#Override
public void DepoisDeExecutar(UploadFoto tarefa) {
if (tarefa.getResposta()[0].equals("200")) {
GlobalModel.getPerfil().setIdDaImagem(WebService.imgURL + tarefa.getResposta()[1].replace("\"", ""));
profilePic.setImageUrl(GlobalModel.getPerfil().getIdDaImagem(), imageLoader);
}
}
});
mUpload.execute();
} catch (NullPointerException e) {
e.printStackTrace();
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
overridePendingTransition(R.anim.animation_back, R.anim.animation_back_leave);
}
#Override
protected void onResume() {
super.onResume();
CarregarPerfil mCarrega = new CarregarPerfil();
mCarrega.execute();
}
}
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:wheel="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<include
android:id="#+id/toolbar_user"
layout="#layout/toolbaruser" />
<RelativeLayout
android:id="#+id/campoImagem"
android:layout_width="fill_parent"
android:layout_height="200dp"
android:layout_below="#+id/toolbar_user"
android:background="#color/armadillo">
<com.android.volley.toolbox.NetworkImageView
android:id="#+id/foto"
android:layout_width="200dp"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="#drawable/user"
android:visibility="visible" />
<com.pnikosis.materialishprogress.ProgressWheel
android:id="#+id/progress_wheel"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center"
android:visibility="gone"
wheel:matProg_barColor="#color/white"
wheel:matProg_progressIndeterminate="true"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<ImageView
android:id="#+id/cropped"
android:layout_width="200dp"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:visibility="visible"/>
<ImageView
android:id="#+id/camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:padding="15dp"
android:src="#drawable/ic_camera" />
<TextView
android:id="#+id/Button_crop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:gravity="center"
android:padding="15dp"
android:text="Salvar"
android:textColor="#color/white"
android:visibility="gone" />
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<TextView
android:id="#+id/membro"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:gravity="center"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingTop="5dp"
android:text="Membro Retornar desde Julho de 2015"
android:textColor="#color/star_dust" />
</RelativeLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/campoImagem"
android:layout_marginBottom="30dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="15dp"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingBottom="0dp"
android:paddingLeft="10dp"
android:paddingRight="0dp"
android:paddingTop="10dp"
android:text="Nome"
android:textColor="#color/star_dust"
android:textSize="#dimen/text1" />
<TextView
android:id="#+id/nome_usuario"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingBottom="0dp"
android:paddingLeft="10dp"
android:paddingTop="5dp"
android:textColor="#color/armadillo"
android:textSize="#dimen/text1" />
<TextView
android:id="#+id/entrar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:text="E-mail"
android:textColor="#color/star_dust"
android:textSize="#dimen/text1" />
<TextView
android:id="#+id/email_usuario"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingBottom="0dp"
android:paddingLeft="10dp"
android:paddingTop="5dp"
android:text="jgvidotto#gmail.com"
android:textColor="#color/armadillo"
android:textSize="#dimen/text1" />
</LinearLayout>
</RelativeLayout>
Because you have not posted your Activity calling the Navigation Drawer, so I have used both your CircledNetworkImageView class and built-in NetworkImageView in my project. It works well. Please refer to the following:
CustomNavigationDrawer.java:
public class CustomNavigationDrawer {
private static ActionBarDrawerToggle sDrawerToggle;
public static DrawerLayout setUpDrawer(final Context context) {
final Activity activity = ((Activity) context);
DrawerLayout sDrawerLayout = (DrawerLayout) activity.findViewById(R.id.drawer_layout);
if (activity.getActionBar() != null) {
activity.getActionBar().setDisplayHomeAsUpEnabled(true);
activity.getActionBar().setHomeButtonEnabled(true);
}
sDrawerToggle = new ActionBarDrawerToggle(
activity,
sDrawerLayout,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close
) {
public void onDrawerClosed(View view) {
activity.invalidateOptionsMenu();
syncState();
}
public void onDrawerOpened(View drawerView) {
activity.invalidateOptionsMenu();
syncState();
}
};
sDrawerLayout.setDrawerListener(sDrawerToggle);
return sDrawerLayout;
}
public static void syncState() {
sDrawerToggle.syncState();
}
public static void onConfigurationChanged(Configuration newConfig) {
sDrawerToggle.onConfigurationChanged(newConfig);
}
}
MainActivity.java:
public class MainActivity extends Activity {
final Context mContext = this;
final String mUrl = "http://.../getimage";
NetworkImageView mNetworkImageView;
CircledNetworkImageView mCircledNetworkImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CustomNavigationDrawer.setUpDrawer(this);
mNetworkImageView = (NetworkImageView) findViewById(R.id.networkImageView);
mNetworkImageView.setImageUrl(mUrl, VolleySingleton.getInstance(mContext).getImageLoader());
mCircledNetworkImageView = (CircledNetworkImageView) findViewById(R.id.circleImageView);
mCircledNetworkImageView.setImageUrl(mUrl, VolleySingleton.getInstance(mContext).getImageLoader());
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
CustomNavigationDrawer.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
CustomNavigationDrawer.onConfigurationChanged(newConfig);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}
activity_main.xml:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<com.android.volley.toolbox.NetworkImageView
android:id="#+id/networkImageView"
android:layout_width="300dp"
android:layout_height="wrap_content" />
<com.example.networkimageview.CircledNetworkImageView
android:id="#+id/circleImageView"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_below="#+id/networkImageView" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
You can create a new sample project and use my sample code. Hope this helps!
if (width == 0 && height == 0 && !isFullyWrapContent) {
I guess the first you loadImage code will return because of this condition. The width and height is equal to 0 before the whole UI load success. log before this condition return. Hope this can help you.
Here am developed a puzzle game, image tiles place in gridview, but the thing is, I would like to fill complete device screen width or device screen height with those tiles.
Here is my result.
Here is my code, please tell me where am doing mistake.
public class ImageBreaking_Activity extends Activity implements OnClickListener {
Button b_save, view_bb;
private Bitmap b;
int position;
ImageButton b_90, b_360;
GridView grid;
String filePath,biks;
Bitmap selectedphoto_bitmap;
int row, col, val;
ArrayList<Bitmap> imageChunks = new ArrayList<Bitmap>();
ArrayList<Bitmap> imageChunks_child = new ArrayList<Bitmap>();
ArrayList<Bitmap> duplicate_bitmaps, duplicate_bitmaps_dump;
public ArrayList<MyBitamp> itemList_dump = new ArrayList<MyBitamp>();
public ArrayList<MyBitamp> itemList_dump__c = new ArrayList<MyBitamp>();
View v_duplicate;
private int count;
ImageAdapter__c adapter;
boolean clicked = false;
private int touchedItemPos = 0;
private MyBitamp tile;
AlertDialog.Builder ad;
DisplayMetrics metrics;
private int Screenwidth;
private int Screenheight;
int gameScreen_width,gameScreen_height;
private int width_bitmap;
private int height_bitmap;
#SuppressWarnings("static-access")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_breaking_);
// screen width x Height
grid = (GridView) findViewById(R.id.grid);
b_90 = (ImageButton) findViewById(R.id.imageButton1);
b_90.setOnClickListener(this);
view_bb = (Button) findViewById(R.id.button2);
view_bb.setOnClickListener(this);
b_360 = (ImageButton) findViewById(R.id.imageButton2);
b_360.setOnClickListener(this);
// side vices
filePath = this.getIntent().getStringExtra("File_path");
biks = this.getIntent().getExtras().getString("File_path_biks");
Log.i("W x H", "biks:" + biks);
selectedphoto_bitmap = decodeFile(filePath);
Log.i("Bitmap Width x Height", selectedphoto_bitmap.getWidth()+"& &"+selectedphoto_bitmap.getHeight());
// bitmap width x height
width_bitmap=selectedphoto_bitmap.getWidth();
height_bitmap=selectedphoto_bitmap.getHeight();
if(selectedphoto_bitmap.getWidth()>selectedphoto_bitmap.getHeight()){
val = selectedphoto_bitmap.getWidth()%selectedphoto_bitmap.getHeight();
// showing if bitmap width is higher than bitmap height, then rotating to 90 degrees
Matrix matrix = new Matrix();
matrix.postRotate(90);
selectedphoto_bitmap = Bitmap.createBitmap(selectedphoto_bitmap, 0, 0,
selectedphoto_bitmap.getWidth(), selectedphoto_bitmap.getHeight(),
matrix, true);
}else{
val=selectedphoto_bitmap.getHeight()%selectedphoto_bitmap.getWidth();
}
// for rows and cols
col=selectedphoto_bitmap.getWidth()/val;
row=selectedphoto_bitmap.getHeight()/val;
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
break_up(selectedphoto_bitmap);
super.onStart();
}
private void break_up(Bitmap selectedphoto_bitmap) {
// TODO Auto-generated method stub
int chunkHeight, chunkWidth,A;
imageChunks = new ArrayList<Bitmap>(col * row);// size of array let us go for 12 or 16
// for perfect square tile
chunkHeight = selectedphoto_bitmap.getHeight() / row;// setting height for tile
chunkWidth = selectedphoto_bitmap.getWidth() / col;// setting width for tile
Log.i("Main Activity_chuck bitmap", chunkHeight
+ " <--chunk__h & chunk__w-->" + chunkWidth);
Log.i("Main Activity_bitmap row and col", col + ":cols & Rows:" + row);
int yCoord = 0;
for (int x = 0; x < row; x++) {
int xCoord = 0;
for (int y = 0; y < col; y++) {
// adding those tile to the array
imageChunks.add(Bitmap.createBitmap(selectedphoto_bitmap,
xCoord, yCoord, chunkWidth, chunkHeight));
xCoord += chunkWidth;
Log.i("Array bitmap", "" + imageChunks.get(y).getWidth()
+ "<-- w & H-->" + imageChunks.get(y).getHeight());
}
yCoord += chunkHeight;
}
Log.i("TAG", "no of size" + imageChunks);
Log.i("TAG", "no of size" + imageChunks.size());
}
private Bitmap decodeFile(String f) {
try {
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale++;
}
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
}
return null;
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
for (int i = 0, j = imageChunks.size(); i < j; i++) {
// taken one model class and passing width,height, id, item_position, rotation
MyBitamp item_dump = new MyBitamp(imageChunks.get(i)
.getWidth(), imageChunks.get(i).getHeight(),
imageChunks.get(i), i, i, 0);
itemList_dump.add(item_dump);
}
Collections.shuffle(itemList_dump);// shuffling the items
Random randomGenerator = new Random();// random number for rotation
int randomInt = randomGenerator.nextInt(4);
for (int i = 0, j = itemList_dump.size(); i < j; i++) {
itemList_dump.get(i).setItemCurPos(i);// set the item current position
itemList_dump.get(i).setrotation(randomInt);// set the rotation
}
adapter = new ImageAdapter__c(this);// custom adapter
grid.setAdapter(adapter);
grid.setNumColumns(col);
grid.setColumnWidth(imageChunks.get(0).getWidth());
grid.setStretchMode(GridView.NO_STRETCH);
super.onResume();
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.button1:
Toast.makeText(this, "Clicked on save", 1).show();
break;
case R.id.imageButton1:
/* rotate view */
tile = itemList_dump.get(touchedItemPos);
if (b_90.isEnabled() && clicked) {
int fix_rotation = tile.getrotation();
if (fix_rotation != 0) {
if (fix_rotation == 0) {
fix_rotation = 0;
tile.setrotation(fix_rotation);
} else {
if (fix_rotation == 2) {
tile.setrotation(3);
} else
if (fix_rotation == 1) {
tile.setrotation(2);
} else if (fix_rotation == 3) {
tile.setrotation(0);
}
}
} else {
tile.setrotation(1);
// itemList_dump.get(position).setrotation(1);
}
} else {
Toast.makeText(ImageBreaking_Activity.this,
"select the item to rotate", Toast.LENGTH_LONG).show();
}
adapter.notifyDataSetChanged();
break;
case R.id.imageButton2:
if (b_360.isEnabled() && clicked) {
tile = itemList_dump.get(touchedItemPos);
int fix_rotation__c = (int) tile.getrotation();
if (fix_rotation__c != 0) {
if (fix_rotation__c == 1) {
tile.setrotation(0);
} else if (fix_rotation__c == 2) {
tile.setrotation(1);
} else if (fix_rotation__c == 3) {
tile.setrotation(2);
}
} else {
tile.setrotation(3);
}
} else {
Toast.makeText(ImageBreaking_Activity.this,
"Select item to Rotate", Toast.LENGTH_SHORT).show();
}
adapter.notifyDataSetChanged();
break;
case R.id.button2:
Dialog d = new Dialog(this);
d.setContentView(R.layout.dialog_xml);
ImageView img = (ImageView) d.findViewById(R.id.imageView1);
img.setImageBitmap(selectedphoto_bitmap);
d.show();
break;
default:
break;
}
}
public class ImageAdapter__c extends BaseAdapter implements
OnTouchListener, OnDragListener {
Context context;
int coordinates[] = new int[2];
ArrayList<MyBitamp> item_list_data = new ArrayList<MyBitamp>();
ArrayList<Bitmap> duplicate = new ArrayList<Bitmap>();
Bitmap b;
HashMap<View, Integer> hashMap = new HashMap<View, Integer>();
// ArrayList<MyBitamp> item_list_data_mybit = new ArrayList<MyBitamp>();
int i = 0, temp, temp2, count = 0, mod, position;
private int dest;
private int source;
private ImageView img;
private Integer touchedItemPosition;
private Integer dropedItemPosition;
private MyBitamp Data;
public ImageAdapter__c(ImageBreaking_Activity context) {
// TODO Auto-generated constructor stub
this.context = context;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return itemList_dump.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return itemList_dump.size();
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int pos, View v, ViewGroup parent) {
// TODO Auto-generated method stub
img = new ImageView(context);
Data = itemList_dump.get(pos);
Data.setItemCurPos(pos);
img.setLayoutParams(new GridView.LayoutParams(itemList_dump
.get(pos).getWidth(), itemList_dump.get(pos).getHeight()));
img.setPadding(1, 1, 1, 1);
img.setImageBitmap(itemList_dump.get(pos).getImageRes());
// rotation
int r_tation__C = itemList_dump.get(pos).getrotation();
if (r_tation__C == 0) {
img.setRotation(0);
} else if (r_tation__C == 1) {
img.setRotation(90);
} else if (r_tation__C == 2) {
img.setRotation(180);
} else if (r_tation__C == 3) {
img.setRotation(270);
}
else {
img.setRotation(360);
}
img.setOnTouchListener(this);
img.setOnDragListener(this);
hashMap.put(img, pos);
if (check_result()) {
Toast.makeText(ImageBreaking_Activity.this, "Success",
Toast.LENGTH_SHORT).show();
ad = new AlertDialog.Builder(ImageBreaking_Activity.this);
ad.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
Intent i_home = new Intent(
ImageBreaking_Activity.this,
HomePage.class);
i_home.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i_home);
ImageBreaking_Activity.this.finish();
}
});
ad.setMessage("Congratulations....!");
ad.setCancelable(false);
ad.show();
}
// more work//
return img;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
v_duplicate = v;
clicked = true;
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (hashMap.containsKey(v)) {
touchedItemPosition = hashMap.get(v);
touchedItemPos = touchedItemPosition;
MyBitamp bitamp = itemList_dump.get(touchedItemPos);
// Toast.makeText(context,
// "current pos:"+bitamp.getItemCurPos()+"original pos"+bitamp.getItemPosition(),Toast.LENGTH_SHORT).show();
v.startDrag(data, shadowBuilder, v, 0);
// item_list_data.get(touchedItemPosition);
}
v.setVisibility(View.INVISIBLE);
return true;
} else
if (event.getAction() == MotionEvent.ACTION_CANCEL) {
v.setVisibility(View.VISIBLE);
return false;
}
else
if (event.getAction() == MotionEvent.ACTION_MOVE) {
return false;
}
else if (event.getAction() == MotionEvent.ACTION_UP) {
}
return false;
}
#Override
public boolean onDrag(View v, DragEvent event) {
dropedItemPosition = hashMap.get(v);
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
// do nothing
break;
case DragEvent.ACTION_DRAG_ENTERED:
break;
case DragEvent.ACTION_DRAG_EXITED:
break;
case DragEvent.ACTION_DROP:
swapItemPositions(dropedItemPosition, touchedItemPosition);
break;
case DragEvent.ACTION_DRAG_ENDED:
Log.i("Drop", "end");
default:
break;
}
return true;
}
void swapItemPositions(int current, int target) {
MyBitamp tempBitmap = itemList_dump.get(current);
itemList_dump.set(current, itemList_dump.get(target));
itemList_dump.set(target, tempBitmap);
notifyDataSetChanged();
}
private boolean check_result() {
boolean isCompleted = false;
for (int i = 0; i < itemList_dump.size(); i++) {
int posit_fix = itemList_dump.get(i).getItemPosition();
int posit_current = itemList_dump.get(i).getItemCurPos();
int rotation = itemList_dump.get(i).getrotation();
if (((posit_fix == posit_current) && rotation == 0)) {
isCompleted = true;
} else {
isCompleted = false;
break;
}
}
if (isCompleted) {
// success
} else {
// failure
}
return isCompleted;
}
}
}
My xml file,
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#223344" >
<GridView
android:id="#+id/grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/linearLayout1"
android:layout_alignParentRight="true" >
</GridView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="SAVE" />
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="true"
android:src="#drawable/plus_90" />
<ImageButton
android:id="#+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="true"
android:src="#drawable/minus_90" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="VIEW" />
</LinearLayout>
</RelativeLayout>
Provide solution, Thank you
You should use Gridview width as fill_parent or match_parent. Currently you are using wrap_content which gives the grid only the space contained by your ImageView. Thats why you are getting the gap
<GridView
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/linearLayout1"
>
</GridView>
Hope this helps.
Use this grid view
<GridView
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="5dp"
android:columnWidth="100dp"
android:fastScrollEnabled="true"
android:horizontalSpacing="10dp"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp"
/>
change your gridview like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#223344" >
<GridView
android:id="#+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/linearLayout1"
>
</GridView>
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="SAVE" />
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="true"
android:src="#drawable/plus_90" />
<ImageButton
android:id="#+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="true"
android:src="#drawable/minus_90" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="VIEW" />
</LinearLayout>
</RelativeLayout>
I use custom CursorAdapter with custom items.
I need height of view to resize Bitmap from assets folder and set this resized bitmap to ImegeView in list item;
#Override
public void bindView(View view, final Context context, final Cursor cursor) {
final ViewHolder holder = (ViewHolder) view.getTag();
final int imgCol = cursor.getColumnIndex(TableOdelice.COLUMN_URL);
int titleCol = cursor.getColumnIndex(TableOdelice.COLUMN_TITRE);
final int themeCol = cursor.getColumnIndex(TableOdelice.COLUMN_THEME);
String tempPath = getPath(cursor.getString(themeCol), cursor.getString(imgCol));
final String path = tempPath.replace(".", "c.");
String[] arr = cursor.getString(titleCol).split("\\*");
holder.title.setText(arr[0]);
holder.subTitle.setText(arr[1]);
if (itemHeight > 0) {
showThumb(itemHeight, holder.img, path);
} else {
final ImageView v = holder.mainImage;
v.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
itemHeight = v.getHeight();
showThumb(itemHeight, holder.img, path);
}
});
}
}
private void showThumb(int height, final ImageView iv, final String path) {
if (thumbs.containsKey(path)) {
iv.setImageBitmap(thumbs.get(path));
} else {
InputStream is = null;
try {
is = context.getAssets().open(path);
} catch (IOException e) {
Log.d("no file at path", path);
e.printStackTrace();
}
if (is != null) {
Bitmap btm = btmHelper.scaleToHeight(BitmapFactory.decodeStream(is);, height);
thumbs.put(path, btm);
iv.setImageBitmap(btm);
}
}
}
For getting view height I use OnGlobalLayoutListener() of view.
But it's very slow ...
Any ideas?
I find answer for my question.
Using this construction I get a correct width or height of view inside adapter for each view.
final ImageView v = holder.mainImage;
v.post(new Runnable() {
#Override
public void run() {
itemHeight = v.getHeight();
Log.d("Height", "" + itemHeight);
}
});
}
Maybe it will help somebody :)
Just give it a try may be it will be faster
v.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
itemHeight = v.getHeight();
showThumb(itemHeight, holder.img, path);
v.getViewTreeObserver().removeGlobalOnLayoutListener( ActivityInsatance);
}
});
If you have top or bottom margins, a bug will appear. When you will scroll this listview, a height of each row will increase. In case of v.getViewTreeObserver().addOnGlobalLayoutListener it will grow infinitely. So, my solution follows.
holder.layout.post(new Runnable() {
#Override
public void run() {
int height = holder.layout.getMeasuredHeight(); // Total row height.
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) holder.textView.getLayoutParams();
holder.textView.setHeight(height - lp.topMargin - lp.bottomMargin);
});
where holder.layout is a link to root RelativeLayout of an adapter's row.