Java Canvas to XML Layout "Hello World" syntax - java

I have a simple xml layout that looks like this:
<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=".ColorWheel1Activity">
<TextView
android:text="#string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="Color Wheel 1"
android:id="#+id/Target"
/>
</RelativeLayout>
and a java script in the form of:
public class ColorWheel1Activity extends Activity {
Paint black = new Paint();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
black.setColor(Color.BLACK);
black.setStrokeWidth(5);
canvas.drawOval(100, 200, 1000, 1100, black);
//don'tknow what to put here
}
I want to draw the oval on the canvas to the inside of the ImageView (android:id Target) in the xml layout but don't know how to do this. I have tried setContentView(R.layout.activity_color_wheel1.xml) which sets the xml layout without drawing the picture. I have also tried setContnetView(canvas) and a few of it's variants which set the entire screen as the canvas, displaying the oval but none of the xml Layout. I have made attempts to locate the Target ImageView with findViewById() but these either crashed the app or did nothing.
I do not want to create an entire xml Layout in java.

I have made attempts to locate the Target ImageView with findViewById() but these either crashed the app or did nothing.
Im not sure how locating the Target Imageview would cause a crash; this definitely seems like the way to go. Try getting a reference to Target, like so
ImageView Target = (ImageView) findViewById(R.id.Target);
Then set the bitmap you created to that ImageView:
Target.setImageBitmap(bitmap);

Related

Dynamically created TextView in FrameLayout has no width

I'm trying to add a TextView in code to a framelayout. This sits above an imageview in the z order of the framelayout. The ultimate aim is to allow the creation of a screenshot from the framelayout that shows the image and the text that has been overlayed on to it. I have this working when using a textview created in xml but not in the dynamic code version. The create bitmap method returns an error complaining about the width of the textbox being 0. In the code below I am trying to capture just the textview as an image to identify what the issue is, as the captured image from the framelayout did not contain the contents of the textview as expected. In doing this I was able to find the width error and I believe it is this that is the root of the problem. I have tried to set the textview's width using setWidth and also using the LayoutParams. The end result is always that the textview has no width although it can be seen on the handset clearly. I think I am missing something between the dynamic creation and the existing xml which results in the 0 width. Can anyone point me in the correct direction please?
The code is as follows
public void applyTextToImage(View view) {
// Do something in response to button
//Hide the virtual keyboard
InputMethodManager inputManager = (InputMethodManager) getSystemService(this.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
//Get the text to overlay on the image
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
//Bring the overlay layout to the front
//LinearLayout overlay_layout = (LinearLayout) findViewById(R.id.image_Overlay_Layout);
//overlay_layout.bringToFront();
//Apply the new text to the text box
/* Old code to get the view that is shown in the layout
TextView text_overlay = (TextView) findViewById(R.id.image_Overlay);
text_overlay.bringToFront();
text_overlay.setText(message);
*/
//New code to create a view dynamically instead
TextView text_Overlay = new TextView(this);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
text_Overlay.setId(Utils.generateViewId());
}
else
{
text_Overlay.setId(TextView.generateViewId()); //static class
}
FrameLayout image_Layout = (FrameLayout) findViewById(R.id.image_Layout);
//View image_Layout = (View) findViewById(R.id.image_Layout);
//FrameLayout.LayoutParams fParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.WRAP_CONTENT);
FrameLayout.LayoutParams fParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.WRAP_CONTENT);
fParams.gravity = Gravity.CENTER;
// text_Overlay.setMaxWidth(image_Layout.getWidth());
// text_Overlay.setWidth(image_Layout.getWidth());
//image_Layout.addView(text_Overlay, fParams);
image_Layout.addView(text_Overlay, fParams);
Toast.makeText(this,"TextView Width: " + text_Overlay.getWidth(),Toast.LENGTH_LONG).show();
//TODO: Something has forced the dynamic layout to not be saved in the bitmap try removing the params and set the values on the textview itself
//TODO: for some reason the width keeps coming back as 0 could be that the image_Layout is 0 too
text_Overlay.setGravity(Gravity.CENTER);
text_Overlay.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());
//text_Overlay.setWidth(250dp);
text_Overlay.setTextSize(pixels);
text_Overlay.setTextColor(Color.RED);
text_Overlay.bringToFront();
text_Overlay.setText(message);
text_Overlay.setVisibility(View.VISIBLE);
//End of new dynamic code
if (folderCheck()){
try {
String filePath = getFilePath();
int myId = text_Overlay.getId();
Bitmap bitmap;
View v1 = findViewById(myId);
v1.setDrawingCacheEnabled(true);
v1.buildDrawingCache();
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
// End imported code
streamBitmapToFile(bitmap, filePath);
}
catch (Exception e)
{
Toast.makeText(this,e.getMessage(),Toast.LENGTH_LONG);
Log.e("Bitmap Creation","Couldn't create bitmap error as: " + e.toString());
}
}
}
XML contents
<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="false">
<!--app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_my"-->
<EditText android:id="#+id/edit_message"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="#string/edit_message"
android:enabled="false"/>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send"
android:onClick="applyTextToImage"
android:enabled="false"
android:id="#+id/overlayButton"/>
</LinearLayout>
<FrameLayout
android:id="#+id/image_Layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true">
<ImageView
android:id="#+id/image_View"
android:layout_width="match_parent"
android:layout_height="250dp" />
<!--<TextView
android:id="#+id/image_Overlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textAlignment="center"
android:textSize="25dp"
android:textColor="#ff0000"/>-->
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="false"
android:gravity="bottom"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true">
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/open_gallery"
android:onClick="openGallery">
</Button>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/new_image"
android:onClick="newImage">
</Button>
</LinearLayout>
</RelativeLayout>
The view has not been measured yet. Until the system does another layout pass, the view reports its width as zero.
In my opinion, you are better off leaving the TextView in the XML layout and simply making it invisible (android:visibility="invisible") until you need it, then make it visible prorammatically with setVisbility(View.VISIBLE). (Note that if you set it to be gone, it will also not be measured.)
For reference Karakuri pointed out the weaknesses and the path to follow to resolve them.
Extra code that was implemented for the listener is as follows.
IMAGE_CAPTURE_REQUESTED = true;
// New Listener
ViewTreeObserver vto = image_Layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
image_Layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
else
{
image_Layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
if (IMAGE_CAPTURE_REQUESTED) {
//int myId = text_Overlay.getId();
//Toast.makeText(MyActivity.this, "Text Overlay Width " + text_Overlay.getWidth() ,Toast.LENGTH_LONG).show();
overlayTextAndExportImage();
}
}
}); //End New Listener
The new overlayTextAndImportImage calls all the image creation routines after the layout has been redrawn.

How do I programmatically position an ImageView in AndroidStudio

I want to position my ImageView in Android Studio so it can be in the same place (ratio wise) throughout the many screen sizes of Android phones.
this is my code in 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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.slippysam.sooper_fly.slippysam.MainActivity"
android:background="#drawable/bgday">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxHeight="40dp"
android:maxWidth="40dp"
android:adjustViewBounds="true"
android:src="#drawable/sam"
android:id="#+id/samm"
/>
</RelativeLayout/>
and here is a function I tried using in my Activity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
positionSam();
}
public void positionSam(){
final ImageView sam = (ImageView)findViewById(R.id.samm);
DisplayMetrics dm = getApplicationContext().getResources().getDisplayMetrics();
float dpHeight = dm.heightPixels / dm.density;
float dpWidth = dm.widthPixels / dm.density;
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) sam.getLayoutParams();
lp.leftMargin = (int) ((dpWidth * 0.5));
lp.topMargin = (int) ((dpHeight * 1.0555));
sam.setLayoutParams(lp);
}
}
this function does indeed change the position of my ImageView however it's position still isn't concrete when I switch between products.
In your layout (RelativeLayout) you need to specify where the ImageView should be placed.
You could try with the attribute android:centerInParent="true" for instance, so your layout file would look something like this:
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.slippysam.sooper_fly.slippysam.MainActivity"
android:background="#drawable/bgday">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxHeight="40dp"
android:maxWidth="40dp"
android:adjustViewBounds="true"
android:centerInParent="true"
android:src="#drawable/sam"
android:id="#+id/samm" />
</RelativeLayout/>
By using centerInParent="true" you don't need to center the ImageView programmatically as you're doing it right now.
If you still want to do it programmatically, you can add a rule to your LayoutParams like this:
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) sam.getLayoutParams();
lp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
sam.setLayoutParams(lp);
And then forget about setting the margin for the ImageView.
To use it programmatically, you will need to call your positionSam() method every time a new image is shown.
okay, so my first method was basically correct; I just needed to edit my RelativeLayout to this:
<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:paddingBottom="0px"
android:paddingLeft="0px"
android:paddingRight="0px"
android:paddingTop="0px"
tools:context="com.slippysam.sooper_fly.slippysam.MainActivity"
android:background="#drawable/bgday">
changing the paddingBottom paddingLeft and etc. helps the function become more accurate in where I need the ImageView to be. I hope this reaches to anybody who needs it.

How to get rid of the strip behind a button from xml in Android Studio?

When i try to import a button from an xml layout file into my View, I get a white strip running vertically along the button when I run the app. The button is found in my layout xml file which I used to integrate with the View. A screenshot can be shown here:(Button is at bottom left of the screen) http://i844.photobucket.com/albums/ab9/lewweihao93/ScreenHunter_01%20Jul.%2026%2018.20_zpsa1idaeao.jpg
The following is the xml code of my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="bottom"
android:text="FIRE"
android:id="#+id/b" />
</LinearLayout>
The following is the relevant part of my main code:
protected void onCreate(Bundle savedInstanceState) {
layout = (LinearLayout) View.inflate(this, R.layout.mbb, null);
super.onCreate(savedInstanceState);
surfaceview=new mbbs(this);
surfaceview.setOnTouchListener(this);
layout.addView(surfaceview);
b=(Button)findViewById(R.id.b);
shot=new SoundPool(5, AudioManager.STREAM_MUSIC,0);
id=shot.load(this, R.raw.shots,1);
bomb=new SoundPool(5, AudioManager.STREAM_MUSIC,0);
id2=bomb.load(this, R.raw.bomb, 1);
Bundle basket2=getIntent().getExtras();
difficulty=basket2.getString("key");
if (difficulty.equals("e"))
{pace=2;}
else if (difficulty.equals("m"))
{pace=5;}
else if (difficulty.equals("h"))
{pace=10;}
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
plusv = BitmapFactory.decodeResource(getResources(),R.drawable.plusv);
minusv = BitmapFactory.decodeResource(getResources(),R.drawable.minusv);
launch = BitmapFactory.decodeResource(getResources(),R.drawable.launch);
target = BitmapFactory.decodeResource(getResources(),R.drawable.target);
cannon = BitmapFactory.decodeResource(getResources(),R.drawable.cannon);
bg = BitmapFactory.decodeResource(getResources(),R.drawable.bg);
setContentView(layout);
tx=1000;tx2=1000;tx3=1000;tx4=1000;tx5=1000;
bx=0;
How do I get rid of the vertical strip along the button?Is this a good way to integrate a layout into a View?

ZoomControls on Google Maps API - how can I move it above a ButtonBar?

I have enabled the built in zoom controls in my google maps application, however, it shows on my footer button panel:
I want the zoom controls to be one top of the footer button bar.
public class MinuteMapActivity extends MapActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// the methods on the map are initialised here - onCreate
zoomControls();
satelliteDisplay();
snapToMap();
}
// method for Zoomcontrols
private void zoomControls() {
LinearLayout zoomControls = (LinearLayout) findViewById(R.id.zoomControls);
MapView zoomLayout = (MapView) findViewById(R.id.MapView);
//zoomControls.addView(zoomLayout, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
zoomLayout.setBuiltInZoomControls(true);
}
XML Layout:
?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.google.android.maps.MapView
android:id="#+id/MapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="0zZsLcQS5Zeiqjbo1n8-nn2CqtxKIuTq2T6bskg"
/>
<!-- set zoom controls on map at the bottom -->
<LinearLayout
android:id="#+id/zoomControls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
/>
If I enable
//zoomControls.addView(zoomLayout, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
it crashes.
Some assistance on how I can move the zoomcontrols above the bottom bar.
I think the reason it crashes is because you are trying to assign LinearLayout parameters to a layout inside a RelativeLayout, so you would have to use RelativeLayout.LayoutParams instead.
Also, I am a bit confused as to why you are using a LinearLayout for your zoom controls instead of the pre-defined View called ZoomControls. Perhaps it would save you a bit of time?
If you want to place the zoom controls above your bottom view use
<ZoomControls
android:id="#+id/zoomControls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_above="#+id/buttonbar" />
assuming you call your ButtonBar view buttonbar.
May you have missed the two line of code in your
<com.google.android.maps.MapView.
so paste this two lines in it and you will got it. its working 100 percent.
android:enabled="true"
android:clickable="true"

My background image is being drawn too big for the canvas

The background I'm trying to draw for my app seems to be getting scaled too large for some reason. I made sure the emulator is WVGA800, have it set up in the manifest and layout to be full screen and landscape (just like the image which is 800 x 480). I just don't see where it would scale the image.
Here's a picture of the problem. The image when put in the emulator, and then the actual image.
Here's some relavant code:
/* mBackground instantiated in the class constructor */
mBackground = BitmapFactory.decodeResource( mContext.getResources(), R.drawable.background );
private void doDraw( Canvas canvas )
{
canvas.drawBitmap( mBackground, 0, 0, null );
}
Here's the layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<com.project.game.GameView
android:id="#+id/game"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
</FrameLayout>
one possibility is to create a canvas with a viewport
public void onDraw(Canvas canvas) {
Bitmap myImg = BitmapFactory.decodeResource(getResources(),
R.drawable.cal_blank);
canvas.setViewport(800, 480);
canvas.drawBitmap(iconImg, 0, 0, new Paint(););
}
another way is to scale your image with this method http://www.anddev.org/resize_and_rotate_image_-_example-t621.html
Just a guess - maybe it depends on what folder type is used to put the image in. Could you say where did you put the image? I mean, is it the /res/drawable-hdpi/ or anything else? Have you tried /res/drawable-nodpi/?

Categories