How to render a tricky ass NinePatch? - android

This is thebasic idea, but the image is ugly and pixelated. WHY???
public class Main extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView iv = (ImageView) findViewById(R.id.iv);
Bitmap bmap = BitmapFactory.decodeResource(getResources(), R.drawable.btn_default_normal);
NinePatchDrawable npd = new NinePatchDrawable(bmap, bmap.getNinePatchChunk(), new Rect(0,0,512,512), "name");
npd.mutate();
npd.setBounds(new Rect(0,0,512,512));
npd.invalidateSelf();
Bitmap bp = Bitmap.createBitmap(512,512, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bp);
npd.draw(canvas);
FileOutputStream ofo=null;
try {
ofo = openFileOutput("image", MODE_WORLD_READABLE);
} catch (IOException e) {
e.printStackTrace();
}
bp.compress(Bitmap.CompressFormat.PNG, 100, ofo);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra(Intent.EXTRA_STREAM, getFileStreamPath("image").toURI());
intent.setType("image/png");
//startActivity(intent);
iv.setImageDrawable(new BitmapDrawable(bp));
}
}

You're making it infinitely more complicated than it needs to be. Just set your view in the XML like so:
<TextView
android:background="#android:drawable/btn_default_small"
android:layout_width="512px"
android:layout_height="wrap_content"
android:text="NinePatch View"
/>
Just using TextView as an example. The same will work for an ImageView, a View, pretty much any widget. The important thing to remember is to use the background attribute instead of the src attribute for an ImageView. The src attribute will stretch the image as is, it won't respect the NinePatch data.
If you're set on doing it in code, just use:
iv.setBackgroundResource(R.drawable.btn_default_small)
As a side note, what device are you displaying it on? Most mobile phones only have up to 480 pixels for the width.

Related

invisible view in WindowManager with type RGBA_8888 ImageView

I often use the attribute, but this time it is not work.If a remove the attribute,I can see the view and everything is ok. Do someone know what am i missed?
myCode:
private boolean loadingDirect=false;
private void addLoading(){
loadingImg= new ImageView(mContext);
android.view.WindowManager.LayoutParams viewParams = new android.view.WindowManager.LayoutParams();
viewParams.x=0;
viewParams.y=0;
viewParams.width=600;
viewParams.height=600;
// viewParams.type=PixelFormat.RGBA_8888;
loadingImg.setImageResource(R.drawable.notice_loading);
loadingImg.setVisibility(View.VISIBLE);
loadingDirect=true;
loadingImg.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
if(loadingDirect){
Matrix matrix = new Matrix();
matrix.setRotate(180);
BitmapDrawable draw = (BitmapDrawable) mContext.getResources().getDrawable(R.drawable.notice_loading);
Bitmap bitmap= draw.getBitmap();
bitmap=Bitmap.createBitmap(bitmap,0, 0, bitmap.getWidth(),bitmap.getHeight(),matrix,true);
loadingImg.setImageBitmap(bitmap);
loadingDirect=false;
}else{
loadingImg.setImageResource(R.drawable.notice_loading);
loadingDirect=true;
}
}
});
try{
mWindowManager.addView(loadingImg, viewParams);
}catch(Exception e){
Log.d("NoticeBoardERROR", "addLoading");
}
}
Please take a look at http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html
Your viewParams.type does not expect PixelFormat.RGBA_8888 or PixelFormat.whatever; your code compile just because they are actually int numbers. But it is not an expected behavior.

Sandboxview with multiple imageview

I'm using Fredrik Bornander's SandBoxView from this tutorial
http://www.codeproject.com/Articles/319401/Simple-Gestures-on-Android
It works efficiently for an imageview but I want to use multiple imageviews. Here is my code under GestureActivity but It still works for only one imageview.
Can anyone help me about this?
public class GesturesActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.d);
SandboxView s = new SandboxView(this, bitmap);
Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.a);
SandboxView s2 = new SandboxView(this, bitmap2);
RelativeLayout ly=new RelativeLayout(this);
ly.addView(s);
ly.addView(s2);
setContentView(ly);
}
The problem is that that control isn't being laid out with any LayoutParameters and it will always take all of the available space if that is the case, so you get two SandboxViews overlapping and that means only the top one receives the touch events.
To fix this (without too much hassle) change the layout to make sure the available space is split between the two controls;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.d);
SandboxView s = new SandboxView(this, bitmap);
Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.a);
SandboxView s2 = new SandboxView(this, bitmap2);
LinearLayout l = new LinearLayout(this);
l.setOrientation(LinearLayout.VERTICAL);
// Note the weight parameter of 1, making sure they split the space between them
LayoutParams lp1 = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 1);
LayoutParams lp2 = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 1);
l.addView(s, lp1);
l.addView(s2, lp2);
setContentView(l);
}
This is easier to do if you add the three constructors to SandboxView from it's base class View, that will allow the control to show up in the designer and it's a lot easier to play around with the layout in there (which is admittedly what I should have done in the first place when I wrote the article).

Saving a drawing done using FingerPaint.java code in android

I have done a sample painting app using APIDemo's FingerPaint app. Instead of the "usual" pattern of setContentView(R.layout.main) it uses a class MyView that extends View and sets content as setContentView(new MyView(this)); now whatever I draw I want to save it in the SDCard. For this I require to know the rootview using getRootView. This is got by the object of layout(for ex: LinearLayout L1 = new...) L1.getRootView. Because I am using this MyView, I am not able to get the rootview nor able to save the bitmap.
myview.setDrawingCacheEnabled(true);
myview.requestFocus();
myview.getRootView();
System.out.println("MYVIEW = "+myview);
myview.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
myview.layout(0, 0, myview.getMeasuredWidth(), myview.getMeasuredHeight());
myview.buildDrawingCache(true);
mBitmap = myview.getDrawingCache();
//System.out.println("myview.getDrawingCache() = "+newview.getDrawingCache());
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
myview.setDrawingCacheEnabled(false); // clear drawing cache
System.out.println("BITMAP = "+mBitmap);
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + "test.jpg");
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
} catch (Exception e)
{
e.printStackTrace();
}
I want to know how do I save my drawing using a menu button click?
Thank you
After a lot of effort into research I bumped into this http://blahti.wordpress.com/2010/11/18/how-to-save-jpeg-files-in-the-android-emulator/ This solved my issue of saving the drawing.

android:enlarging an image on click

I am making an android app in which i need to enlarge the image size on click.
I am getting these images downloaded from server and then adding these images programmatically in the activity and hence setting id of images programmatically. Now my problem is that when i send the imageid o another activity to enlarge it it is taking only the id of last image.
and hence gives the following exception.
Unable to start activity ComponentInfo{com.emx.OnDaMove/com.emx.OnDaMove.FullImageActivity}: android.content.res.Resources$NotFoundException: Resource ID #0x5
i am using the following code for making images and adding them to table rows.
imageUrl = "http://ondamove.it/English/images/users/";
imageUrl = imageUrl + listObject.get(j).getImage();
image = new ImageView(this);
image.setPadding(20, 10, 0, 0);
image.setId(j+1);
imageId=image.getId();
tr.addView(image);
and the following method for clickliastener:
private OnClickListener clickImageListener = new OnClickListener() {
public void onClick(View v) {
Intent fullScreenIntent = new Intent(v.getContext(),FullImageActivity.class);
fullScreenIntent.putExtra(ProfilePageNormalUser.class.getName(),imageId) ;
ProfilePageNormalUser.this.startActivity(fullScreenIntent);
}
};
and the activity in which images are to be enlarged is:
ImageView myimage = (ImageView) findViewById(R.id.imageviewEnlarged);
Intent intent = getIntent();
int imageId = (Integer) intent.getExtras().get(ProfilePageNormalUser.class.getName());
System.out.println("********"+imageId +"**********");
InputStream is = this.getResources().openRawResource(imageId);
Bitmap originalBitmap = BitmapFactory.decodeStream(is);
Matrix imageMatrix = new Matrix();
imageMatrix.postRotate(90);
Bitmap scaledBitmap = Bitmap.createBitmap(originalBitmap, myimage.getWidth(), myimage.getHeight(), originalBitmap.getWidth(), originalBitmap.getHeight(), imageMatrix, false);
myimage.setImageBitmap(scaledBitmap);
myimage.setScaleType(ScaleType.FIT_XY);
Ya surely it will give the last Id since the value of imageId will be update on every loop. This will store the last known value during looping.
You should use array instead of simple variable.
or you can use v.getId in onClick method. (simpler one)

Android: showing default image in gallery's ImageView while actual image is downloaded

I believe this is pretty trivial but I can't get it to work.
I want to display a default image in gallery elements (ImageViews) while their actual image is being fetched from the net.
Right now, nothing is shown for an ImageView which its image has yet to arrive. Once it arrives it is immediately shown.
What I tried is right after the instantiation of the ImageView to call its setImageResource function like so:
final ImageView i = new ImageView(mContext);
i.setImageResource(R.drawable.loading);
But it doesn't seem to work. Below is the full getView() function.
Any help is appreciated.
Thanks.
public View getView(int position, View convertView, ViewGroup parent) {
final ImageView i = new ImageView(mContext);
i.setImageResource(R.drawable.loading);
// if the drawbale is in the buffer - fetch it from there
Drawable bufferedImage = DataManager.getInstance().getImagesBuffer()[position];
if (bufferedImage != null){
i.setImageDrawable(bufferedImage);
BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
drawable.setAntiAlias(true);
}
// if drawable is not in buffer - fetch it from the net via AsyncImageLoader
else
{
String imageUrl = DataManager.getInstance().getImageBufferInstance().getImageUrl(position);
Drawable downloadedImage = AsyncImageLoader.getInstance().loadDrawable(imageUrl, new ImageCallback() {
public void imageLoaded(Drawable imageDrawable, String imageUrl) {
if (imageDrawable == null)
{
imageDrawable = getResources().getDrawable(R.drawable.icon);
}
i.setImageDrawable(imageDrawable);
BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
drawable.setAntiAlias(true);
}
});
i.setImageDrawable(downloadedImage);
}
i.setLayoutParams(new CoverFlow.LayoutParams(Utils.getInstance().getScreenWidth() / 2,
Utils.getInstance().getScreenHeight() / 2));
i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
return i;
}
Fix your indentation... If I'm reading that correctly, you're only setting the temporary drawable icon in the imageLoaded callback of your (not shown) AsyncImageLoader, which I assume means it's then only being set after the image downloads and is then immediately overwritten with the downloaded image. Try moving the placeholder-setting code into your else block outside the callback.

Categories

Resources