I'm loading a bitmap from the input stream and putting it on an imageview. THen I have a button that should draw a circle on the bitmap. The error is that the imageview (called 'touch') is not found inside the onClickListener...how do I fix this? When I press the button nothing happens. (Note: ZoomInZoomOut class is an extension of Imageview)
try {
java.io.FileInputStream in = this.openFileInput(path);
Bitmap bitmap = BitmapFactory.decodeStream(in);
ZoomInZoomOut touch = (ZoomInZoomOut)findViewById(R.id.IMAGEID);
touch = arrangeImageView(touch);
touch.setImageBitmap(bitmap);
in.close();
Button draw = (Button) findViewById(R.id.draw);
draw.setOnClickListener(new View.OnClickListener(){
public void onClick(View v)
{
Bitmap imageBitmap = Bitmap.createBitmap(200,
200, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(imageBitmap);
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(Color.BLUE);
canvas.drawCircle(60, 50, 25, p);
/////////////////////Error is on the next line:
touch.setImageBitmap(imageBitmap);
}
});
} catch (Exception e) {
e.printStackTrace();
}
Here is 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"
android:background="#drawable/background"
tools:context="com.commonsware.android.test1.ImageDisplayActivity"
>
<com.commonsware.android.test1.ZoomInZoomOut
android:id="#+id/IMAGEID"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="o"
android:id="#+id/draw"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
The touch variable is defined in another scope. If you want more explication, check this link.
To fix your problem change your code like this:
final ZoomInZoomOut touch = (ZoomInZoomOut)findViewById(R.id.IMAGEID);
Or you can also create a variable in your class if you need to access it from another scope later:
private ZoomInZoomOut touch;
and instantiate like this:
touch = (ZoomInZoomOut)findViewById(R.id.IMAGEID);
Related
I have assigned a bitmap to a full-screen ImageView with canvas while streaming. Streaming works, the bitmap is shown in ImageView, but the active area of ImageView seems to be smaller than it's actual size. When I set the background color to ImageView, I get this result:
background fills only a small part of marked ImageView...
I assume this is the reason, why all my efforts to scale the bitmap to the size of ImageView do not work.
Here's my layout xml:
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingBottom="#dimen/activity_vertical_margin">
<ImageView
android:id="#+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DCD5D5"
android:rotation="90"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:onClick="take_photo"
android:text="#string/take_photo"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Assigning bitmap to ImageView:
public void run() {
if (mLastFrame != null) {
mutableBitmap = mLastFrame.copy(Bitmap.Config.RGB_565, true);
if (moffset == OFFSET) {
mBitmap = Bitmap.createBitmap(iv_heigth, iv_width, Bitmap.Config.RGB_565);
mCameraView.setImageBitmap(mBitmap);
mCanvas = new Canvas(mBitmap);
mCanvas.drawBitmap(mutableBitmap, 0, 0, null);
moffset += OFFSET;
}
}
}
ImageView size iv_width, iv_height is checked in onCreate function as follows:
ViewTreeObserver viewTreeObserver = mCameraView.getViewTreeObserver(); //check imageview size
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
mCameraView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//do some things
iv_width = mCameraView.getWidth();
iv_heigth = mCameraView.getHeight();
}
});
}
I am totally frustrated, hopefully, someone can help a lonely beginner...
This is due to the rotation that was applied to the ImageView. If you remove the rotation, you will be able to see that the ImageView is back to normal. The height of the Imageview is actually matching parent and the same goes for width as well. However, when it is rotated by 90 degrees, you can see the width as the height of the ImageView and vice versa.
In order to tackle this problem, I would recommend removing the rotation from the xml layout that you applied to the ImageView. You can do that for your bitmap drawable instead. Before setting it into the ImageView, rotate the drawable by 90 degrees and then set it to the view.
Here are a few clever ways of rotating a bitmap by 90 degrees. I am just copying one answer from this post for convenience.
public static Bitmap rotateBitmap(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
I hope that helps!
I am new to Android and I want to draw 3 circles in a fixed position.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView imgCircle = (ImageView) findViewById(R.id.imgCircle);
final ImageView imgCircle1 = (ImageView) findViewById(R.id.imgCircle1);
final ImageView imgCircle2 = (ImageView) findViewById(R.id.imgCircle2);
//first
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);
paint.setStyle(Paint.Style.FILL);
paint.setAlpha(50);
Bitmap bmp = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
canvas.drawCircle(bmp.getWidth()/2, bmp.getHeight()/2, 150, paint);
imgCircle.setImageBitmap(bmp);
(the second and the third circles have the same code as the first one)
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="#+id/activity_main"
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.example.andav.wisersteps_v2.MainActivity"
android:background="#drawable/foot">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#mipmap/ic_launcher"
android:id="#+id/imgCircle2"
tools:ignore="ContentDescription"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="34dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#mipmap/ic_launcher"
android:id="#+id/imgCircle1"
tools:ignore="ContentDescription"
android:layout_marginTop="21dp"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/imgCircle2"
android:layout_toEndOf="#+id/imgCircle2"
android:layout_marginLeft="18dp"
android:layout_marginStart="18dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#mipmap/ic_launcher"
android:id="#+id/imgCircle"
tools:ignore="ContentDescription"
android:layout_marginTop="53dp"
android:layout_below="#+id/imgCircle1"
android:layout_alignLeft="#+id/imgCircle1"
android:layout_alignStart="#+id/imgCircle1" />
</RelativeLayout>
The problem is that main_activity positions (where I want to draw the circles) does not match the emulator positions:
before && after
How can I resolve this?
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.
I want to put three images on a vertical scroll view, I don't know why, but I just see the third one ( tuto3 ).
here is the xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/scrollView" >
<LinearLayout
android:id="#+id/linearLayout42"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</LinearLayout>
</ScrollView>
</LinearLayout>
And there the class:
public class about extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aboutlayout);
LinearLayout ll = (LinearLayout) findViewById(R.id.linearLayout42);
ImageView image = new ImageView(about.this);
image.setBackgroundResource(R.drawable.tuto1);
ll.addView(image);
ImageView image2 = new ImageView(about.this);
image.setBackgroundResource(R.drawable.tuto2);
ll.addView(image2);
ImageView image3 = new ImageView(about.this);
image.setBackgroundResource(R.drawable.tuto3);
ll.addView(image3);
}
}
You keep calling setBackgroundResource on image instead of image, image1, and image2.
I have a class named SeatsPanel where I draw seats (using drawRect) in the onDraw method. The onDraw method uses Canvas as a parameter, but how do you set size of the Canvas? The reason why I'm asking this question is because this class is being inflated in another class. I know that the canvas has the default height and width of the phone, but I need to make it smaller. How can I do this?
Any help would be appreciated.
I've tried to implement a simple application that draws a black rect within the main activity, that is drawn pushing a button. For example, in the MainActivity:
private Button button1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button1=(Button)findViewById(R.id.button);
button1.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
switch(v.getId()){
case R.id.button:
LinearLayout ll=(LinearLayout)findViewById(R.id.linearLayout1);
System.out.println(ll.getWidth()+" "+ll.getHeight());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ll.getWidth(),ll.getHeight());
YourView yourView = new YourView(getBaseContext());
yourView.setBackgroundColor(Color.WHITE);
ll.addView(yourView,params);
break;
}
}
});
}
And in the YourView class:
private Bitmap savedBitmap;
public YourView(Context context) {
super(context);
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
System.out.println(canvas.getWidth()+" "+canvas.getHeight());
Paint textPaint = new Paint();
textPaint.setARGB(255, 0, 0, 0);
textPaint.setTextAlign(Paint.Align.RIGHT);
textPaint.setTextSize(11);
textPaint.setTypeface(Typeface.DEFAULT);
canvas.drawColor(Color.WHITE);
System.out.println(canvas.getWidth());
System.out.println(canvas.getHeight());
canvas.drawRect(200, 20, 500, 100, textPaint);
}
The main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Push the button and draw a Rect" />
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</LinearLayout>
Might not be applicable in your case, but this works for me
Bitmap animation = BitmapFactory.decodeResource(mContext.getResources(), resourceId, mBitmapOptions); //Get a bitmap from a image file
// Create a bitmap for the part of the screen that needs updating.
Bitmap bitmap = Bitmap.createBitmap(animation.getWidth(), animation.getHeight(), BITMAP_CONFIG);
bitmap.setDensity(DisplayMetrics.DENSITY_DEFAULT);
Canvas canvas = new Canvas(bitmap);
This sets the canvas to the size of the bitmap