I've googled a lot finding a lot of solutions for problems similar to mine but not equal.
I have to show a jpg file (as an Ad banner not full screen) that is stored on a server (internet).
I've tried using WebView, but, when the screen width is bigger than the image width, the image appears smaller than the screen.
Is it possible to use ImageView instead of WebView?
If 'Yes' how can I scale the downloaded image to fit different screen resolutions?
Thanks in advance.
Here the solution find there https://stackoverflow.com/a/9288544/2252143:
MainActivity.java:
public class MainActivity extends Activity {
ImageView imgProva = null;
FunzioniUtili Funzioni = new FunzioniUtili();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imgProva = (ImageView)findViewById(R.id.imgProva);
// show The Image
new DownloadImageTask((ImageView) findViewById(R.id.imgProva)).execute("http://www.softlive.net/advs/banner_adolfo.jpg");
}
public void onClick(View v) {
startActivity(new Intent(this, MainActivity.class));
finish();
}
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) {
bmImage.setImageBitmap(result);
int DisplayWidth = 0;
DisplayWidth = Funzioni.ScreenWidth (MainActivity.this);
double CardResizeFactor=1.0;
//This is the function that I use to resize... / CardResizer is redundant, I know!
Funzioni.scaleImage(bmImage,(int)(DisplayWidth / CardResizeFactor),0,0);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
My resize function:
/**
* public void scaleImage(ImageView view, int boundBoxInDp)
*
* Resize the given ImageView.
*
* #param view The ImageView.
* #param boundBoxInDp Scaling factor in Dp.
* #param layoutType 0 = RelativeLayout 1 = LinearLayout 2 = TableLayout 3 = TableRow 4 = FrameLayout.
* #param colNumber Column number if the selected layout is TableRow. If other, put 0
*/
public void scaleImage(ImageView view, int boundBoxInDp, int layoutType, int colNumber)
{
// Get the ImageView and its bitmap
Drawable drawing = view.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
// Get current dimensions
int width = bitmap.getWidth();
int height = bitmap.getHeight();
// Determine how much to scale: the dimension requiring less scaling is
// closer to the its side. This way the image always stays inside your
// bounding box AND either x/y axis touches it.
float xScale = ((float) boundBoxInDp) / width;
float yScale = ((float) boundBoxInDp) / height;
float scale = (xScale <= yScale) ? xScale : yScale;
// Create a matrix for the scaling and add the scaling data
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
// Create a new bitmap and convert it to a format understood by the ImageView
Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
BitmapDrawable result = new BitmapDrawable(scaledBitmap);
width = scaledBitmap.getWidth();
height = scaledBitmap.getHeight();
// Apply the scaled bitmap
view.setImageDrawable(result);
// Now change ImageView's dimensions to match the scaled image
if(layoutType == 0)
{
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
params.width = width;
params.height = height;
view.setLayoutParams(params);
}
else if(layoutType == 1)
{
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();
params.width = width;
params.height = height;
view.setLayoutParams(params);
}
else if(layoutType == 2)
{
TableLayout.LayoutParams params = (TableLayout.LayoutParams) view.getLayoutParams();
params.width = width;
params.height = height;
view.setLayoutParams(params);
}
else if(layoutType == 3)
{
TableRow.LayoutParams params = (TableRow.LayoutParams) view.getLayoutParams();
params.width = width;
params.height = height;
params.column = colNumber;
}
else if(layoutType == 4)
{
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams();
params.width = width;
params.height = height;
view.setLayoutParams(params);
}
}
Here my Activity_Main.xml:
<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=".MainActivity" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<ImageView
android:id="#+id/imgProva"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:src="#drawable/ic_launcher" />
</RelativeLayout>
you can set the width of the image to 100% with css
see
http://www.w3schools.com/cssref/pr_dim_width.asp
I am using this to display an png image. It will stretch the image to fill the screen vertically keeping its aspect ratio. It seems to only work on API 11+ tho. It's in a RelativeLayout.
<ImageView
android:id="#+id/main_imageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:src="#drawable/img_alchemy2" />
Ok, I've found the solution and I've edited the question adding the code.
Thanks.
Related
I am new to Android development and I could use some help!
I am trying to create a GridView to display 1 image loaded 9 times with different filters. I am using the GPUImage framework for Android and the Universal Image Loader.
Here is what I have so far:
public class FilterActivity extends Activity {
private MyApplication mApp;
private ArrayList<GPUImageFilter>filters;
public ArrayList<Bitmap>bitmaps;
private List<String> filterNames;
int maxWidth = 120;
int maxHeight = 120;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filter);
Uri imageURI = mApp.getFirstImagePath();
ImageLoader imageLoader = ImageLoader.getInstance();
BitmapFactory.Options resizeOptions = new BitmapFactory.Options();
resizeOptions.inSampleSize = 3; // decrease size 3 times
resizeOptions.inScaled = true;
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.decodingOptions(resizeOptions)
.postProcessor(new BitmapProcessor() {
#Override
public Bitmap process(Bitmap bmp) {
return scaleBitmap(bmp);
}
})
.build();
Bitmap bmp = imageLoader.loadImageSync(imageURI.toString(), options);
filterNames = Arrays.asList("grayscale", "documentary", "sepia",
"posterize", "noFilter", "lomo",
"cool", "warm", "vignette");
for (String filterName : filterNames ){
filters.add(filterWithName(filterName));
}
GPUImage mGPUImage = new GPUImage(this);
mGPUImage.getBitmapForMultipleFilters(bmp,filters, new GPUImage.ResponseListener<Bitmap>() {
#Override
public void response(Bitmap bitmap) {
bitmaps.add(bitmap);
}
});
GridView gridView = (GridView) findViewById(R.id.gridViewFX);
gridView.setAdapter(new ImageAdapter(this));
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
}
private Bitmap scaleBitmap(Bitmap bm) {
int width = bm.getWidth();
int height = bm.getHeight();
Log.v("Pictures", "Width and height are " + width + "--" + height);
if (width > height) {
// landscape
float ratio = (float) width / maxWidth;
width = maxWidth;
height = (int)(height / ratio);
} else if (height > width) {
// portrait
float ratio = (float) height / maxHeight;
height = maxHeight;
width = (int)(width / ratio);
} else {
// square
height = maxHeight;
width = maxWidth;
}
Log.v("Pictures", "after scaling Width and height are " + width + "--" + height);
bm = Bitmap.createScaledBitmap(bm, width, height, true);
return bm;
}
private GPUImageFilter filterWithName(String name) {
GPUImageFilter mGPUImageFilter;
switch (name) {
default:
case "noFilter":
mGPUImageFilter = new GPUImageContrastFilter(.5f);
break;
case "grayscale":
mGPUImageFilter = new GPUImageGrayscaleFilter();
break;
case "documentary":
float[] color = new float[]{1.f, 1.f, 1.f, 1.f};
mGPUImageFilter = new GPUImageMonochromeFilter(.8f, color);
break;
case "sepia":
mGPUImageFilter = new GPUImageSepiaFilter(.85f);
break;
case "posterize":
mGPUImageFilter = new GPUImagePosterizeFilter();
break;
case "lomo":
mGPUImageFilter = new GPUImagePixelationFilter();
break;
case "cool":
GPUImageLookupFilter amatorka = new GPUImageLookupFilter();
amatorka.setBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.lookup_amatorka));
mGPUImageFilter = amatorka;
break;
case "warm":
mGPUImageFilter = new GPUImageCrosshatchFilter();
break;
case "vignette":
PointF centerPoint = new PointF();
centerPoint.x = 0.5f;
centerPoint.y = 0.5f;
mGPUImageFilter = new GPUImageVignetteFilter(centerPoint, new float[]{0.0f, 0.0f, 0.0f, 0.0f}, 0.3f, 0.75f);
break;
}
return mGPUImageFilter;
}
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return bitmaps.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageBitmap(bitmaps.get(position));
return imageView;
}
}
}
and the xml:
<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" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.andreaskaitis.myapplication.FilterActivity">
android:background="#drawable/background">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/layoutX">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="75dp"
android:text="#string/effects"
android:layout_gravity="center_horizontal"
android:textColorHint="#ffffffff"
android:textColor="#ffffffff"
android:shadowColor="#000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
/>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="50dp"
android:background="#drawable/layout_bg"
android:alpha="1"
android:id="#+id/roundedLayout">
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridViewFX"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:horizontalSpacing="4dip"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="4dip"
android:padding="4dip" />
</LinearLayout>
</LinearLayout>
When I try to compile I get this:
04-07 04:36:12.453 1527-1527/com.example.andreaskaitis.myapplication I/Choreographer﹕ Skipped 37 frames! The application may be doing too much work on its main thread.
04-07 04:36:12.485 1527-1565/com.example.andreaskaitis.myapplication W/dalvikvm﹕ threadid=22: thread exiting with uncaught exception (group=0xa4c40648)
04-07 04:36:12.485 1527-1565/com.example.andreaskaitis.myapplication E/AndroidRuntime﹕ FATAL EXCEPTION: GLThread 119
java.lang.NullPointerException
at jp.co.cyberagent.android.gpuimage.GPUImageRenderer$3.run(GPUImageRenderer.java:184)
at jp.co.cyberagent.android.gpuimage.GPUImageRenderer.runAll(GPUImageRenderer.java:126)
at jp.co.cyberagent.android.gpuimage.GPUImageRenderer.onDrawFrame(GPUImageRenderer.java:115)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1523)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
Any help with pointing out what I am doing wrong and how to fix it will be greatly appreciated!
I tried lot for thumbnails but finally I got only one solution for thumbnails.
mGPUImage.capture(60,60) will return you bitmap with applied filter of size 60 x 60 . So you can generate thumbnails by this way and apply you logic for multiple filters thumbnails.
Hope this will work for you.
i want ImageView's to look same on different screen sizes. To make it easier for you to understand how it should look there are some image:
Biggest problem is that my imageViews are created programmatically. ImageViews layout and size are set by this code
LinearLayout LinearLayoutas = (LinearLayout)findViewById(R.id.LinearLayout);
ImageView ImageViewas = new ImageView(this);
ImageViewas.setScaleType(ImageView.ScaleType.FIT_CENTER);
LinearLayoutas.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
ImageViewas.setLayoutParams(params);
ImageViewas.getLayoutParams().height = 650;
ImageViewas.getLayoutParams().width = 950;
params.setMargins(0, 50, 0, 0);
Any ideas how to change this code that my app can look same on diffrent screen sizes?
Well, you can retrieve device resolution and set imageView width and height. Here is the solution.
private class ScreenResolution {
int width;
int height;
public ScreenResolution(int width, int height) {
this.width = width;
this.height = height;
}
}
#SuppressLint("NewApi")
#SuppressWarnings("deprecation")
ScreenResolution deviceDimensions() {
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
// getsize() is available from API 13
if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2) {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return new ScreenResolution(size.x, size.y);
}
else {
Display display = getWindowManager().getDefaultDisplay();
// getWidth() & getHeight() are deprecated
return new ScreenResolution(display.getWidth(), display.getHeight());
}
}
..................
LinearLayout LinearLayoutas = (LinearLayout)findViewById(R.id.LinearLayout);
ImageView ImageViewas = new ImageView(this);
ImageViewas.setScaleType(ImageView.ScaleType.FIT_CENTER);
LinearLayoutas.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
ScreenResolution screenRes = deviceDimensions();
ImageViewas.setLayoutParams(params);
ImageViewas.getLayoutParams().height = screenRes.height;
ImageViewas.getLayoutParams().width = screenRes.width;
params.setMargins(0, 50, 0, 0);
Also when the device orientation will be changed, the width and height should be swapped. You can do that in onConfigurationChanged:
#Override
public void onConfigurationChanged(Configuration newConfiguration) {
super.onConfigurationChanged(newConfiguration);
// swap device width and height here and re-assign
}
I'm trying to make a splash screen like FB's app, where the logo moves up and the login stuff appears. I don't know why, but this doesn't work properly:
public class Login extends Activity {
ImageView logo;
int width, height;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
logo = (ImageView) findViewById(R.id.logo);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (logo != null) {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x / 2;
height = size.y / 2;
TranslateAnimation animation = new TranslateAnimation(width, width,
height, height / 2);
animation.setDuration(2500);
animation.setFillAfter(false);
animation.setAnimationListener(new MyAnimationListener());
logo.startAnimation(animation);
// /////
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.login, menu);
return true;
}
private class MyAnimationListener implements AnimationListener {
#Override
public void onAnimationEnd(Animation animation) {
logo.clearAnimation();
LayoutParams lp = new LayoutParams(logo.getWidth(),
logo.getHeight());
lp.setMargins((int) width, (int) height / 2, 0, 0);
logo.setLayoutParams(lp);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
}
}
I'm trying to move an ImageView vertically, starting from the screen's center:
width = size.x / 2;
height = size.y / 2;
Instead of that, the ImageView moves vertically from right bottom corner.
1. Why dividing the screen size / 2 doesn't position the ImageView in the center of it?
2. After the animation ends, I set the new LayoutParams to the ImageView: lp.setMargins((int) width, (int) height / 2, 0, 0);. Shouldn't that position it in the place that the animation ends? Instead of that, it's getting pushed to the left.
XML:
<LinearLayout 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"
android:background="#drawable/background"
android:gravity="center"
tools:context=".Login" >
<ImageView
android:id="#+id/logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/logo" />
Thanks in advance :)
I've tried to set my ImageView resized but it did not work either by bitmap or other methods I'm going to place my code so if can anyone help me how to size the ImageView to fit inside the table row thnx.
public class Test extends Activity
{
private TableLayout Table1;
protected void onCreate(Bundle savedInstanceState)
{
int[] ImageArray={R.raw.hospital_image,R.raw.hotel_image};
super.onCreate(savedInstanceState);
setContentView(R.layout.favorites);
Table1 = (TableLayout) findViewById(R.id.Table);
TableRow.LayoutParams tableRowParams = new TableRow.LayoutParams(
TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT, 1.0f);
for(int i=0;i<ImageArray.length;i++)
{
TableRow TR = new TableRow(this);
TR.setLayoutParams(tableRowParams);
ImageView img=new ImageView(this);
//What should i do here to resize it ???
Drawable d = getResources().getDrawable(ImageArray[i]);
img.setImageDrawable(d);
TR.addView(img, new TableRow.LayoutParams(
TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT, 1.0f));
Table1.addView(TR);
}
}
My XMl only holds these :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
<TableLayout
android:id="#+id/Table1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</TableLayout>
</ScrollView>
</RelativeLayout>
try this,
public class ResizableImageView extends ImageView {
public ResizableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ResizableImageView(Context context) {
super(context);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable d = getDrawable();
if (d == null) {
super.setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
return;
}
int imageHeight = d.getIntrinsicHeight();
int imageWidth = d.getIntrinsicWidth();
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
float imageRatio = 0.0F;
if (imageHeight > 0) {
imageRatio = imageWidth / imageHeight;
}
float sizeRatio = 0.0F;
if (heightSize > 0) {
sizeRatio = widthSize / heightSize;
}
int width;
int height;
if (imageRatio >= sizeRatio) {
// set width to maximum allowed
width = widthSize;
// scale height
height = width * imageHeight / imageWidth;
} else {
// set height to maximum allowed
height = heightSize;
// scale width
width = height * imageWidth / imageHeight;
}
setMeasuredDimension(width, height);
}
}
use it in your layout as you would plain old ImageView, just change the tag, like this,
<com.example.ResizableImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:padding="1px"
android:scaleType="fitCenter"
android:src="..." />
setLayoutParams() should do the trick, in your case I believe you would need TableRow.LayoutParams, like so:
ImageView img = new ImageView(this);
img.setLayoutParams(new TableRow.LayoutParams(w, h));
Edit
Try to set the Drawable before the setLayoutParams:
ImageView img = new ImageView(this);
Drawable d = getResources().getDrawable(ImageArray[i]);
img.setImageDrawable(d);
img.setLayoutParams(new TableRow.LayoutParams(w, h));
I am a programmer with a Windows background and I am new to Java and Android stuff.
I want to create a widget (not an app) which displays a chart. After a long research I know I can do this with Canvas, imageviews and Bitmaps. The canvas which I paint on should be the same as the Widget Size.
How do I know the widget size (or imageview size) so that I can supply it to the function?
Bitmap.createBitmap(width_xx, height_yy, Config.ARGB_8888);
Code Snippet:
In the timer run method:
#Override
public void run() {
Bitmap bitmap = Bitmap.createBitmap(??, ??, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// Create a new paint
Paint p = new Paint();
p.setAntiAlias(true);
p.setStrokeWidth(1);
// Draw circle
// Here I can use the width and height to scale the circle
canvas.drawCircle(50, 50, 7, p);
remoteViews.setImageViewBitmap(R.id.imageView, bitmap);
From what I've learnt, you can only calculate widget dimensions on Android 4.1+.
When on a lower API, you'll have to use static dimensions.
About widget dimensions: App Widget Design Guidelines
int w = DEFAULT_WIDTH, h = DEFAULT_HEIGHT;
if ( Build.VERSION.SDK_INT >= 16 ) {
Bundle options = appWidgetManager.getAppWidgetOptions(widgetId);
int maxW = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH);
int maxH = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT);
int minW = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
int minH = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
if ( context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ) {
w = maxW;
h = minH;
} else {
w = minW;
h = maxH;
}
}
Have a look at the method:
public void onAppWidgetOptionsChanged (Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions)
It will be called each time you start/resize the widget.
Getting the widget width/height can be done as follows:
newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)
newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)
newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)
I am currently using this:
private void run() {
int width = 400, height = 400;
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
Paint p = new Paint();
p.setColor(Color.WHITE);
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(1);
p.setAntiAlias(true);
c.drawCircle(width/2, height/2, radius, p);
remoteViews.setImageViewBitmap(R.id.imageView, bitmap);
ComponentName clockWidget = new ComponentName(context,
Clock_22_analog.class);
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
appWidgetManager.updateAppWidget(clockWidget, remoteViews);
}
You can use this
Bitmap image1, image2;
Bitmap bitmap = Bitmap.createBitmap(image1.getWidth(), image1.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
You can create a custom widget and set the size of wight on its onMeasure() method. And also save the size at that time so that you can use it further for image creation...
I've not worked on Widgets, but I have some experience getting ImageView's size.
Here is some code I use:
public class ViewSizes {
public int width;
public int height;
public boolean isEmpty() {
boolean result = false;
if (0 >= width || 0 >= height) {
result = true;
}
return result;
}
}
That's just a dummy class containing the size parameters.
public static ViewSizes getSizes(View view) {
ViewSizes sizes = new ViewSizes();
sizes.width = view.getWidth();
sizes.height = view.getHeight();
if (sizes.isEmpty()) {
LayoutParams params = view.getLayoutParams();
if (null != params) {
int widthSpec = View.MeasureSpec.makeMeasureSpec(params.width, View.MeasureSpec.AT_MOST);
int heightSpec = View.MeasureSpec.makeMeasureSpec(params.height, View.MeasureSpec.AT_MOST);
view.measure(widthSpec, heightSpec);
}
sizes.width = view.getMeasuredWidth();
sizes.height = view.getMeasuredHeight();
}
return sizes;
}
This method calculates the width forcing a measure cycle if such has not already happened.
public static boolean loadPhoto(ImageView view, String url, float aspectRatio) {
boolean processed = false;
ViewSizes sizes = ViewsUtils.getSizes(view);
if (!sizes.isEmpty()) {
int width = sizes.width - 2;
int height = sizes.height - 2;
if (ASPECT_RATIO_UNDEFINED != aspectRatio) {
if (height * aspectRatio > width) {
height = (int) (width / aspectRatio);
} else if (height * aspectRatio < width) {
width = (int) (height * aspectRatio);
}
}
// Do you bitmap processing here
processed = true;
}
return processed;
}
This one is probably useless for you. I give just as an example - I have an ImageView and image URL, which should be parametrized with image and height.
public class PhotoLayoutListener implements OnGlobalLayoutListener {
private ImageView view;
private String url;
private float aspectRatio;
public PhotoLayoutListener(ImageView view, String url, float aspectRatio) {
this.view = view;
this.url = url;
this.aspectRatio = aspectRatio;
}
boolean handled = false;
#Override
public void onGlobalLayout() {
if (!handled) {
PhotoUtils.loadPhoto(view, url, aspectRatio);
handled = true;
}
ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
removeLayoutListenerPre16(viewTreeObserver, this);
} else {
removeLayoutListenerPost16(viewTreeObserver, this);
}
}
}
#SuppressWarnings("deprecation")
private void removeLayoutListenerPre16(ViewTreeObserver observer, OnGlobalLayoutListener listener){
observer.removeGlobalOnLayoutListener(listener);
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void removeLayoutListenerPost16(ViewTreeObserver observer, OnGlobalLayoutListener listener){
observer.removeOnGlobalLayoutListener(listener);
}
}
This is just a layout listener - I want to process the image loading once the layout phase has finished.
public static void setImage(ImageView view, String url, boolean forceLayoutLoading, float aspectRatio) {
if (null != view && null != url) {
final ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (forceLayoutLoading || !PhotoUtils.loadPhoto(view, url, aspectRatio)) {
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new PhotoLayoutListener(view, url, aspectRatio));
}
}
}
}
This is the method I actually call. I give it the view and URL. The methods takes care of loading - if it can determine the view's size it starts loading immediately. Otherwise it just assigns a layout listener and start the loading process once the layout is finished.
You could strip away some parameters - forceLoading / aspectRatio should be irrelevant for you. After that change the PhotoUtils.loadPhoto method in order to create the bitmap with the width / height it has calculated.
Like Julian told us, you can get them like that with a bitmap of your image:
int width = bitmap.getWidth();
int height = bitmap.getHeight();