I need your help with an Android custom view and the methods getX() and getY(): I'm trying to paint a simple circle at view.getX() and view.getY(), but the circle hasn't its center in the top-left corner as I expect. See the image below (the custom View is the green rectangle):
This is my custom view code:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class PlotterView extends View {
private Paint paint;
public PlotterView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setColor(Color.BLUE);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(this.getX(), this.getY(),5, paint);
}
}
And this is the entire layout:
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="calc.PlotFunctionActivity">
<calc.PlotterView
android:id="#+id/plotter"
android:padding="0dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#00FF00"
android:layout_weight="8"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="2">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="#dimen/plot_text_size"
android:text="f(x)="
android:gravity="center_vertical|end"/>
<EditText
android:id="#+id/function"
android:layout_width="0dp"
android:layout_height="match_parent"
android:textSize="#dimen/plot_text_size"
android:layout_weight="4"
android:gravity="center_vertical|start"/>
<Button
android:id="#+id/plot"
android:layout_width="0dp"
android:layout_height="match_parent"
android:textSize="#dimen/plot_text_size"
android:layout_weight="2"
android:text="#string/plot_button_label"/>
</LinearLayout>
</LinearLayout>
Any suggestion? Thank you in advance.
pskink is totally right, you set a padding to your "base" linearlayout your plot view so when you call getX() it returns you position of plotview in its parent layout (your base linearlayout) landmark (something corresponding to 16dp).
Then when you draw a circle you set circle center in plotview landmark so top-left corner of green view is (0,0). For now you can see the same translation between baselayout-plotview and plotview-circle center.
Related
I'm trying to create an app for drawing some simple lines in a canvas. I want the canvas to take up the top 50% of the screen, leaving the bottom 50% of the screen for buttons and what not. I am currently using setContentView(canvas); which makes it so that the canvas takes up 100% of the screen.
You can create a class that extends View and do drawing inside that view on onDraw() method of that view. Add that view to your layout with any width or height you choose.
Instead of setContentView, use your layout XML to create a view to hold the canvas as shown in Error referencing an inner class View in layout/main.xml.
After that, it's a matter of using a technique in android:layout_height 50% of the screen size such as:
<LinearLayout ...>
<view
class="com.example.foo.FooActivity$Drawer"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
>
</LinearLayout>
You can also use, say, android:layout_weight="0.7" and "0.3" to set the canvas/button container to 70% and 30% of the screen respectively.
Here's a minimal, complete example:
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:keepScreenOn="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:background="#f00"
>
<view
class="com.example.foo.FooActivity$Drawer"
android:background="#00f"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<LinearLayout
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
>
<Button
android:id="#+id/start"
android:text="#string/start"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#f0f"
android:padding="10dp"
android:layout_margin="20dp"
/>
<Button
android:id="#+id/stop"
android:text="#string/stop"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#f0f"
android:padding="10dp"
android:layout_margin="20dp"
/>
</LinearLayout>
</LinearLayout>
Activity:
package com.example.foo;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
public class FooActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_foo);
}
public static class Drawer extends View {
private static Paint paint;
private static int viewWidth;
private static int viewHeight;
public Drawer(Context con, AttributeSet attr) {
super(con, attr);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
}
// https://stackoverflow.com/a/9718512/6243352
#Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
super.onSizeChanged(xNew, yNew, xOld, yOld);
viewWidth = xNew;
viewHeight = yNew;
}
#Override
protected void onDraw(final Canvas c) {
super.onDraw(c);
paint.setARGB(255, 0, 0, 0);
int cx = viewWidth / 2;
int cy = viewHeight / 2;
c.drawCircle(cx, cy,viewWidth / 4, paint);
}
}
}
Result:
When we type an input value by using EditText, I want a horizontal line to be placed below my input like phone book application in all mobile phones.
Enter Phone : ___________
I want my input to be placed on this line. How can I do this by using EditText ?
Try this
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:layout_marginTop="2dp">
<EditText
android:id="#+id/Prac"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Practice"
android:inputType="text"
android:textSize="12sp" />
</android.support.design.widget.TextInputLayout>
You have to set width of EditText from match_parent to wrap_content line below code
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
You have to set width to either match_parent or to fixed width like 100dp
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
As everyone answer said set width and height to wrap_content this is the right answer but still their is another way to achieve this lets have a look.
First create a drawable file (myline.xml) which create the line.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="1dp"
android:left="-2dp"
android:right="-2dp"
android:top="-2dp">
<shape android:shape="rectangle">
<stroke
// You can change width according to your need
android:width="1dp"
android:color="#000000" />
</shape>
</item>
Now in your layout.xml use myline.xml in edit text background.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter Phone: "
android:textColor="#000"
android:textSize="18dp" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/myline"
android:textColor="#000"
android:textSize="18dp" />
</LinearLayout>
And its done see the output in screenshot below.
You can Try with CustomEditText Like Below code:
package com.cj.myapplication;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.EditText;
/**
* Created by E069099 on 7/20/2017.
*/
public class CustomEdiTextWithLine extends EditText {
private Rect rect;
private Paint paint;
public CustomEdiTextWithLine(Context context, AttributeSet attrs) {
super(context, attrs);
rect = new Rect();
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.GREEN);
paint.setStrokeWidth(2F);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setTextSize(20);
}
#Override
protected void onDraw(Canvas canvas) {
//start at the vertical center of the textview
float top = (getHeight() + getPaddingTop() - getPaddingBottom())/2;
//start at the left margin
float left = getPaddingLeft();
//we draw all the way to the right
float right = getWidth() -getPaddingRight();
//we want the line to be 2 pixel thick
float bottom = getHeight()- getPaddingBottom();
canvas.drawLine(0,bottom,right,bottom,paint);
super.onDraw(canvas);
}
}
one method is,
make backgroundtint is black colour and set hint like below code
<EditText
android:layout_width="200dp"
android:layout_height="wrap_content"
android:backgroundTint="#000000"
android:hint=" " />
other method is,
add a view with black background below the editText and background of the editText is make it null.
I have activity_choose_number1.xml
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_choose_number1" />
This is content_choose_number1.xml
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.abc.abc.ChooseNumber1"
tools:showIn="#layout/activity_choose_number1">
<ListView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:id="#+id/listViewNumberList"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp" />
</LinearLayout>
This is secnumsinglechoice.xml
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:checkMark="#null"
android:drawableStart="?android:attr/listChoiceIndicatorSingle"
tools:targetApi="ice_cream_sandwich"
android:textSize="25dp"
android:linksClickable="false"
android:checked="false"
android:paddingTop="20dp"
android:paddingBottom="20dp" />
The secnumsinglechoice.xml is copy paste of android.R.layout.simple_list_item_single_choice and made some changes.
Now what I need is to center align the checkbox and text of secnumusingchoice.xml. I also need the checkbox to be left side of text in each item of list view
Things I tried
1) If I do drawableLeft, it creates space between text and checkbox, but doesn't make both to be centered
2) If I add android:textAlignment="center" then still it center aligns the text but not the check box .
3) I tried here center text and checkmark of CheckedTextView but I would like to try here with more code.
Please help. Thanks.
Is that what you want
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#android:color/white"
android:gravity="center">
<CheckBox
android:id="#+id/ckb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true" />
<TextView
android:id="#+id/tvEduName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="ABC"
android:textSize="17sp" />
</LinearLayout>
Result
To get everything to center correctly, we'll subclass CheckedTextView, and override its onDraw() method to first measure the combined Drawable and text widths and paddings, and then translate the Canvas accordingly before calling the super method to actually do the draw.
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.CheckedTextView;
import android.text.Layout;
public class CenteredCheckedTextView extends CheckedTextView {
public CenteredCheckedTextView(Context context) {
this(context, null);
}
public CenteredCheckedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDraw(Canvas canvas) {
if (getCompoundDrawables()[0] == null) {
super.onDraw(canvas);
}
else {
// Left drawable and paddings width
final float dw = getCompoundDrawables()[0].getIntrinsicWidth() +
getPaddingLeft() + getCompoundDrawablePadding();
// Text width
final float tw = getMaxLineMeasure();
canvas.save();
canvas.translate((getWidth() - (dw + tw)) / 2f, 0f);
super.onDraw(canvas);
canvas.restore();
}
}
private float getMaxLineMeasure() {
final Layout layout = getLayout();
final int lines = getLineCount();
float m = 0, max = 0;
for (int i = 0; i < lines; ++i) {
m = getPaint().measureText(getText(),
layout.getLineStart(i),
layout.getLineEnd(i));
if (m > max) {
max = m;
}
}
return max;
}
}
CheckedTextView has a checkMarkGravity attribute that determines on which end it places the checkMark Drawable, but it's not public, for some odd reason, so we'll just use the drawableLeft. For example:
<com.mycompany.myapp.CenteredCheckedTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:textSize="25dp"
android:drawableLeft="?android:attr/listChoiceIndicatorSingle" />
You might need to slightly fiddle with the translation and/or width values in the custom class to get everything to line up with what looks centered to you, depending on what kind of transparent, intrinsic padding the Drawable has.
How do I dynamically add image buttons on the click of a button? I need to add the image buttons in 2x3 format and it should be horizontally scrollable when it goes out of the screen.
package com.example.dynamic;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class MainActivity extends Activity {
LinearLayout linearLayout1;
LinearLayout linearLayout2;
int flag=0;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_main);
linearLayout1 = (LinearLayout) findViewById(R.id.linearLayout1);
linearLayout2 = (LinearLayout) findViewById(R.id.linearLayout2);
}
public void onClick(View v){
ImageView image = new ImageView(MainActivity.this);
image.setBackgroundResource(R.drawable.ic_launcher);
if(flag==0){
linearLayout1.addView(image);
flag=1;
}
else{
linearLayout2.addView(image);
flag=0;
}
}
}
and this is the layout I used:
<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:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Button" />
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/linearLayout1"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/linearLayout2"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
</LinearLayout>
The problem with this is that, when the number of image button exceeds the screen width, it is not scrollable. Another potential problem is that it might be possible to scroll the 2 rows separately, and not together. and that is not desirable. Please help me, I'm a beginner and pardon me for any mistakes while asking this.
Сurrently there is no horizontal scrollview class in android. You can try some custom scroll views here, here or here. When you will choose which one class to use, you should create adapter, or add items directly into this scroll view. You dont need any layouts inside scroll view.
I want to add marker on GoogleMap like UI Controls (Zoom controls, Compass, MyLocation Button). so that when i swipe on map screen, those positions not change.
https://developers.google.com/maps/documentation/android/interactivity
can anybody tried it before, please suggest me how to do it. I want to use those markers like buttons in my app.
is it possible ?
Best solution is to set an overlay in front of your map using FrameLayout or RelativeLayout and then use it in your Activity.
your xml will look like as Below :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<View
android:id="#+id/your_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#abc" />
<fragment
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"
android:scrollbars="vertical" />
</LinearLayout>
Here is the code that I use to overlay buttons on top of the MapView.
Android Layout
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/home_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:apiKey="YOURAPIKEY"
android:clickable="true"
/>
<com.kyght.yourproject.TransparentPanel
android:gravity="center_horizontal"
android:id="#+id/transparent_panel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<Button android:id="#+id/mapbtncenterme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:padding="5dp"
android:drawableTop="#drawable/ic_menu_mylocation"
android:text="Find ME"/>
Java Class
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
public class TransparentPanel extends LinearLayout
{
private Paint innerPaint, borderPaint ;
public TransparentPanel(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TransparentPanel(Context context) {
super(context);
init();
}
private void init() {
innerPaint = new Paint();
innerPaint.setARGB(225, 75, 75, 75); //gray
innerPaint.setAntiAlias(true);
borderPaint = new Paint();
borderPaint.setARGB(255, 255, 255, 255);
borderPaint.setAntiAlias(true);
borderPaint.setStyle(Style.STROKE);
borderPaint.setStrokeWidth(2);
}
public void setInnerPaint(Paint innerPaint) {
this.innerPaint = innerPaint;
}
public void setBorderPaint(Paint borderPaint) {
this.borderPaint = borderPaint;
}
#Override
protected void dispatchDraw(Canvas canvas) {
RectF drawRect = new RectF();
drawRect.set(0,0, getMeasuredWidth(), getMeasuredHeight());
canvas.drawRoundRect(drawRect, 5, 5, innerPaint);
canvas.drawRoundRect(drawRect, 5, 5, borderPaint);
super.dispatchDraw(canvas);
}
}