I am trying to make part of my image clickable. In this case I have 24 port switch and I want when user click on a port to display the port number. I already have do the zooming and tried to insert rectangles over the image, but I am still new in the Android Development so I am not so sure how to accomplish the task.
Here is my code to create rectangles and put on the picture:
(the idea is that I have one class Rectangles that keeps the port number and some text so I can retrieve them)
public class MainActivity extends Activity{
ImageView DrawingImage;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DrawingImage = (ImageView) this.findViewById(R.id.image);
Bitmap bitmap2 = Bitmap.createBitmap((int) getWindowManager()
.getDefaultDisplay().getWidth(), (int) getWindowManager()
.getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap2);
DrawingImage.setImageBitmap(bitmap2);
// Draw Rectangle
Paint paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.FILL);
float left = 20;
float top = 20;
float right = 50;
float bottom = 100;
canvas.drawRect(left, top, right, bottom, paint);
Zoom image = (Zoom) findViewById(R.id.image);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
image.setImageBitmap(bitmap);
int posX=(int)image.getX();
int posY=(int)image.getY();
double height=image.getHeight();
double width=image.getWidth();
}
}
But when I run the App I cannot see the Rectangle. Even if i declare the picture before the rectangle I can see only the rectangle.
Any suggestions?
Any help will be appreciated.
Thank you in advance!
Best regards,
Dimtiar Georgiev
xml layout:
<FrameLayout 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">
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
onCreate Method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView DrawingImage = (ImageView) this.findViewById(R.id.imageView2);
Bitmap bitmap2 = Bitmap.createBitmap((int) getWindowManager()
.getDefaultDisplay().getWidth(), (int) getWindowManager()
.getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap2);
DrawingImage.setImageBitmap(bitmap2);
// Draw Rectangle
Paint paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.FILL);
float left = 20;
float top = 20;
float right = 50;
float bottom = 100;
canvas.drawRect(left, top, right, bottom, paint);
ImageView image = (ImageView) findViewById(R.id.imageView1);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
image.setImageBitmap(bitmap);
int posX=(int)image.getX();
int posY=(int)image.getY();
double height=image.getHeight();
double width=image.getWidth();
}
Its not about what you draw first now. It's about the xml layout. what to put first. ofcourse you may want to play with the height and width attributes for the image view to achieve what your really want. but this is working I test it.
This will not work. the way you did it.
you must have two image views in your design.
use a framelayout and put two image view inside it.
set the canvas for one of them and draw.
and set the image for the other.
it will not work because you set the first bitmap:
DrawingImage.setImageBitmap(bitmap2);
then you replace it:
image.setImageBitmap(bitmap);
you got the same image layout:
R.id.image
Related
I want to get dimensions of View defined in activity_main.xml to create a Bitmap based on height and width. Writing them in textView shows 0 or stops app. I checked if this view is null, but it's not. Can I get dimensions of view this way?
Here is the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.textView);
View view = (View) findViewById(R.id.view);
int x = view.getMeasuredWidth();
int y = view.getHeight();
int radius = 10;
textView.setText(view.getHeight());
// if (view == null) textView.setText("View is null");
// else textView.setText("View is not null");
Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Here is actvity_main.xml:
<View
android:id="#+id/view"
android:layout_width="400dp"
android:layout_height="400dp"
android:layout_marginLeft="44dp"
android:layout_marginStart="44dp"
android:layout_marginTop="136dp"
android:background="#color/green"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView"
android:layout_width="209dp"
android:layout_height="48dp"
android:layout_marginLeft="44dp"
android:layout_marginStart="44dp"
android:layout_marginTop="28dp"
android:text="TextView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Your are trying to set integer value in TextView in this line textView.setText(view.getHeight()); Try Convert it in String an then set as follows.
textView.setText(String.valueOf(view.getHeight()));
for getting view either use above line in onResume or use as follows
textView.post(new Runnable()
{
public void run()
{
textView.setText(String.valueOf(view.getHeight()));
}
});
I hope it's work for you
Thank You
getWidth and height will return 0 as long as the view has not been layedout.
in order to get the dimensions at the right moment you have 2 options:
add a ViewTreeObserver in onCreate and remove it when it gets called.
2.(i think is easier) add a runnable to the view as i have showed at the bottom:
view.post(new Runnable() {
#Override
public void run() {
int x = view.getMeasuredWidth();
int y = view.getHeight();
}
})
the post() method callback gets called only after the view inflating is done.
happy coding
You can try this solution
int height;
int width;
ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
viewTreeObserver .addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override public void onGlobalLayout () {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
height = view.getLayoutParams().height;
width = view.getLayoutParams().width;
}
});
Just use this code :)
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
Now you can use height and width variable in your project
In Android, I create an ImageView in the Java code and set its layout parameters: width, height and top margin before adding it to the main layout (RelativeLayout). The width and height are applied successfully, but the margin doesn't have any affect on the image view position. The actual top margin stays 0.
How to apply the top margin to views? The code is below.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initClouds();
}
private void initClouds() {
addCloud(R.drawable.cloud1, R.dimen.cloud1_top_margin);
addCloud(R.drawable.cloud2, R.dimen.cloud2_top_margin);
}
private void addCloud(int imageResId, int topMarginResId) {
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.mainLayout);
ImageView cloud = new ImageView(this);
int height = (int) getResources().getDimension(R.dimen.cloud_height);
int width = (int) getResources().getDimension(R.dimen.cloud_width);
ViewGroup.MarginLayoutParams params = new ViewGroup.MarginLayoutParams(width, height);
params.topMargin = (int) getResources().getDimension(topMarginResId);
cloud.setImageResource(imageResId);
mainLayout.addView(cloud, params);
}
}
For setting the margin for a view inside RelativeLayout you should use RelativeLayout.LayoutParams . Change your code like this ,
private void addCloud(int imageResId, int topMarginResId) {
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.mainLayout);
ImageView cloud = new ImageView(this);
int height = (int) getResources().getDimension(R.dimen.cloud_height);
int width = (int) getResources().getDimension(R.dimen.cloud_width);
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(width, height);
param.topMargin = (int) getResources().getDimension(topMarginResId);
cloud.setImageResource(imageResId);
mainLayout.addView(cloud, param);
}
I am trying to get the screen width and height so that I can make a button move randomly on the screen when I click it.
The code I have so far it:
public class MainActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
DisplayMetrics display = this.getResources().getDisplayMetrics();
int width = display.widthPixels;
int height = display.heightPixels;
public void moveMe(View view)
{
Button myButton = (Button) findViewById(R.id.my_button);
Random r = new Random();
int x = (r.nextInt(width));
int y = (r.nextInt(height));
myButton.setX(x);
myButton.setY(y);
}
}
The XML is:
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/my_button"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_x="0dp"
android:layout_y="0dp"
android:text="Yes"
android:onClick="moveMe"/>
</AbsoluteLayout>
However, when I launch the app it says that it has stopped.
The error I get in Android Studio is:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.test.test/com.example.test.test.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
Thankyou for any help you can offer.
You are calling getResources() before the super.onCreate(Bundle) is called. You must call getResources() after onCreate(). Move your code to onCreate or onStart:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DisplayMetrics display = getResources().getDisplayMetrics();
int width = display.widthPixels;
int height = display.heightPixels;
}
Try this inside onCreate:
DisplayMetrics display = this.getResources().getDisplayMetrics();
int width = display.widthPixels;
int height = display.heightPixels
You can use code so that no need to weight till your layout get rendered completely.
Display display = context.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int height = size.y;
int width = size.x;
But in practice AbsoluteLayout is deprecated and its not good way to position Children using absolute positioning may not give same User Interface feel in all devices.Other option suggested by experts is RelativeLayout.
You can find downside of the AbsoluteLayout at the link Absolute positioning pitfalls
Is there away to put buttons/imagebuttons on top of the "game-surface"?
I'm experimenting with code from this blog:
https://www.simplifiedcoding.net/android-game-development-tutorial-1/
I need to change direction for objects on the screen with some buttons.
In the tutorial a ship changes direction if the touch screen is pressed anywhere.
I have tried this:
ImageButton b1 = (ImageButton) findViewById(R.id.turn_left);
in order to add the button later to the view with addView, but it returns null.
Maybe becaue setContentView(gameView); set the view of GameView and not
GameActivity?
Any suggestions on how to make this work?
public class GameActivity extends AppCompatActivity {
private GameView gameView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Getting display object
Display display = getWindowManager().getDefaultDisplay();
//Getting the screen resolution into point object
Point size = new Point();
display.getSize(size);
gameView = new GameView(this, size.x, size.y);
//adding it to contentview
setContentView(gameView);
}
GameView
public class GameView extends SurfaceView implements Runnable {
...code...
private void draw() {
//checking if surface is valid
if (surfaceHolder.getSurface().isValid()) {
//locking the canvas
canvas = surfaceHolder.lockCanvas();
//drawing a background color for canvas
canvas.drawColor(Color.BLACK);
//Drawing the player
canvas.drawBitmap(
...code...
draw);
//Unlocking the canvas
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
....code....
#Override
public boolean onTouchEvent(MotionEvent motionEvent) {
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
...code...
return true;
}
}
XML
xmlns:tools="http://schemas.android.com/tools"
tools:context="package.GameActivity">
<ImageButton
android:id="#+id/turn_left"
android:background="#drawable/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
You can create custom button class which draw bitmap through canvas.
I am programmatically creating textviews with horizontal lines between each view. Using a drawable created programmatically.
The problem is, the opacity starts off light and gradually increases for each line.
I've logged the opacity (getAlpha()) of the drawable, paint, image view and linear layout at all the points in the two methods provided and from the drawables it's always 255 and the views 1.0. I don't understand why it's not behaving as though this is true. I've also tried setting Alpha, it makes no difference.
Why is it doing this and how do I fix it?
xml:
<LinearLayout android:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" .../>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="PaintDashedLines"
android:text="Press Me"/>
</LinearLayout>
java:
static int tvCount = 0;
public void PaintDashedLines(View v) {
LinearLayout ll = (LinearLayout) findViewById(R.id.main);
TextView tv = new TextView(MainActivity.this);
tv.setGravity(Gravity.CENTER);
tv.setTextSize(25);
tv.setPadding(0, 5, 0, 5);
ll.addView(tv);
tv.setText("TextView " + tvCount);
ImageView divider = new ImageView(MainActivity.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
ll.getWidth(), 2);
lp.setMargins(0, 5, 0, 5);
divider.setLayoutParams(lp);
divider.setBackground(CreateDashedLined());
ll.addView(divider);
tvCount++;
}
public static Drawable CreateDashedLined() {
ShapeDrawable sd = new ShapeDrawable(new RectShape());
Paint fgPaintSel = sd.getPaint();
fgPaintSel.setColor(Color.BLACK);
fgPaintSel.setStyle(Paint.Style.STROKE);
fgPaintSel.setPathEffect(new DashPathEffect(new float[]{5, 10}, 0));
return sd;
}
To me looks like more some issue with the emulator. You could also try disable the hardware acceleration with
ll.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Please, keep also in mind that you don't need to instantiate a new ImageView every time, just to draw a divider between the TextViews. You could use setDivider. E.g.
In your onCreate
ShapeDrawable sd = new ShapeDrawable(new RectShape());
sd.setIntrinsicHeight(1);
Paint fgPaintSel = sd.getPaint();
fgPaintSel.setARGB(255, 0, 0, 0);
fgPaintSel.setStyle(Paint.Style.STROKE);
fgPaintSel.setPathEffect(new DashPathEffect(new float[]{5, 10}, 0));
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.main);
linearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE | LinearLayout.SHOW_DIVIDER_END);
linearLayout.setDividerDrawable(sd);
and when you press the button
public void pressMe(View view) {
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.main);
TextView tv = new TextView(MainActivity.this);
tv.setGravity(Gravity.CENTER);
tv.setTextSize(25);
tv.setPadding(0, 5, 0, 5);
tv.setText("TextView " + linearLayout.getChildCount());
linearLayout.addView(tv);
}
the result is