I am making an application in Android and I am currently trying to make a vertical TextView. I want it to look similar to this.
Does anyone know how to achieve this, or at least an existing library which I can use to get this effect.
Thanks
If you want vertical Text View like this then you need to pass \n to Text View text property.
Refer this.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:background="#000"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="5dp"
android:text="A\nB\nC\nD\n"
android:textColor="#FFF"
android:textSize="18dp" />
</RelativeLayout>
You must create custom view
For example:
public class VerticalTextView extends AppCompatTextView {
final boolean topDown;
public VerticalTextView(Context context, AttributeSet attrs) {
super(context, attrs);
final int gravity = getGravity();
if (Gravity.isVertical(gravity) && (gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
setGravity((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) | Gravity.TOP);
topDown = false;
} else
topDown = true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
#Override
protected boolean setFrame(int l, int t, int r, int b) {
return super.setFrame(l, t, l + (b - t), t + (r - l));
}
#Override
public void draw(Canvas canvas) {
if (topDown) {
canvas.translate(getHeight(), 0);
canvas.rotate(90);
} else {
canvas.translate(0, getWidth());
canvas.rotate(-90);
}
canvas.clipRect(0, 0, getWidth(), getHeight(), Region.Op.REPLACE);
super.draw(canvas);
}
}
Related
This question already has answers here:
Put constant text inside EditText which should be non-editable - Android
(18 answers)
Closed 6 years ago.
I want an EditText which displays a fixed text, something like display below.
try this one
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:id="#+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="IN +91"/>
<EditText
android:id="#+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:inputType="textPersonName"
android:hint="Enter mobile number here"/>
</LinearLayout>
Refer this https://medium.com/#ali.muzaffar/adding-a-prefix-to-an-edittext-2a17a62c77e1#.y6uxyppam
public class PrefixEditText extends AppCompatEditText {
float mOriginalLeftPadding = -1;
public PrefixEditText(Context context) {
super(context);
}
public PrefixEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PrefixEditText(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
calculatePrefix();
}
private void calculatePrefix() {
if (mOriginalLeftPadding == -1) {
String prefix = (String) getTag();
float[] widths = new float[prefix.length()];
getPaint().getTextWidths(prefix, widths);
float textWidth = 0;
for (float w : widths) {
textWidth += w;
}
mOriginalLeftPadding = getCompoundPaddingLeft();
setPadding((int) (textWidth + mOriginalLeftPadding),
getPaddingRight(), getPaddingTop(),
getPaddingBottom());
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
String prefix = (String) getTag();
canvas.drawText(prefix, mOriginalLeftPadding,
getLineBounds(0, null), getPaint());
}
}
Usage:
<com.alimuzaffar.customwidgets.PrefixEditText
fontPath="fonts/Lato-Light.ttf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:textSize="24sp"
android:tag="+61 "
android:text="1234" />
OR
android-phone-number-with-flags
[https://github.com/dlukashev/android-phone-number-with-flags
i have a screen filled with buttons in my app and i need to have three specific buttons to turn 90 degree so their text will be turned i tried to use
android:rotation="90"
it fixed my text direction problem but it made it so the button be too small (the button kept their width size)
i need it will look like this
for this three button i need to change (the button that said 1st12 2st12 and 3st12) is:
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="20sp"
android:textStyle="bold"
android:text="1st12"
android:rotation="90"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="20sp"
android:text="2st12"
android:rotation="90"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="20sp"
android:text="3st12"
android:rotation="90"/>
any help will be great thanks
You can custom TextView:
public class VerticalTextView extends TextView{
final boolean topDown;
public VerticalTextView(Context context, AttributeSet attrs){
super(context, attrs);
final int gravity = getGravity();
if(Gravity.isVertical(gravity) && (gravity&Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
setGravity((gravity&Gravity.HORIZONTAL_GRAVITY_MASK) | Gravity.TOP);
topDown = false;
}else
topDown = true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
#Override
protected boolean setFrame(int l, int t, int r, int b){
return super.setFrame(l, t, l+(b-t), t+(r-l));
}
#Override
public void draw(Canvas canvas){
if(topDown){
canvas.translate(getHeight(), 0);
canvas.rotate(90);
}else {
canvas.translate(0, getWidth());
canvas.rotate(-90);
}
canvas.clipRect(0, 0, getWidth(), getHeight(), android.graphics.Region.Op.REPLACE);
super.draw(canvas);
}
}
How do I get height in self-defined layout when i set layout_weight="1" in vertical LinearLayout?
Here is my code:
<LinearLayout
android:id="#+id/timer_layout1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<com.zzb.resume.views.DotView
android:id="#+id/timer_line1"
android:layout_width="2dp"
android:layout_height="30dp" />
<ImageView
android:id="#+id/timer_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/timer_line1"
android:src="#mipmap/time2"/>
<com.zzb.resume.views.DotView
android:id="#+id/timer_line2"
android:layout_width="2dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
In DotView I get height=0. How can I get height when layout_weight="1"?
DotView.java:
public class DotView extends View {
private Paint p;
private int height;
private int dash;
public DotView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public DotView(Context context) {
super(context);
init(context);
}
private void init(Context context) {
p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setStyle(Style.FILL);
p.setColor(context.getResources().getColor(R.color.color_divide));
Log.d("TAG", "--getMeasuredHeight>>" + height);
Log.d("TAG", "--getHeight>>" + getHeight());
final float scale = context.getResources().getDisplayMetrics().density;
dash = (int) (6 * scale + 0.5f);
ViewTreeObserver viewTreeObserver = getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
height = getMeasuredHeight();
Log.d("TAG", "--onGlobalLayout>>" + height);
}
});
}
viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
getViewTreeObserver().removeOnPreDrawListener(this);
height = getMeasuredHeight();
Log.d("TAG", "--onPreDraw>>" + height);
return true;
}
});
}
#Override
protected void onDraw(Canvas canvas) {
if(height>10){
for(int i=0;i<height;i+=dash){
canvas.drawLine(0, i, 0, i+=dash, p);
}
}
super.onDraw(canvas);
}
#Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
height=h;
p.setStrokeWidth(height);
this.postInvalidate();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
height = MeasureSpec.getSize(heightMeasureSpec);
Log.d("TAG", "--onMeasure>>" + height);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Logcat is shown: all result is 0.
You should not get the height in onCreate() , you can set a listener after the view initiates . Here is the code you can see also:
ViewTreeObserver vto = imageView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
vto.removeOnPreDrawListener(this);
int height = imageView.getMeasuredHeight();
int width = imageView.getMeasuredWidth();
return true;
}
});
I hope this may help you.
to achieve this you need to give weightsum in linear layout
<LinearLayout
android:id="#+id/timer_layout1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:weightSum="2"
android:orientation="vertical">
<com.zzb.resume.views.DotView
android:id="#+id/timer_line1"
android:layout_width="2dp"
android:layout_height="30dp" />
<ImageView
android:id="#+id/timer_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/timer_line1"
android:src="#mipmap/time2"/>
<com.zzb.resume.views.DotView
android:id="#+id/timer_line2"
android:layout_width="2dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
I'm trying to remove and add views during onLayout in a ViewGroup, but this causes some child views not to properly redraw.
Consider the following view:
public static class MyViewGroup extends ViewGroup {
View view;
int count;
boolean removeInLayout = true;
public MyViewGroup(Context context) {
super(context);
init();
}
public MyViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyViewGroup(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
view = LayoutInflater.from(getContext()).inflate(R.layout.myview, this, false);
addView(view);
setOnClickListener(new OnClickListener() {
#Override public void onClick(View v) {
count++;
requestLayout();
}
});
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (removeInLayout) {
removeViewInLayout(view);
}
invalidate();
final String text = "Count: " + count;
((TextView) view.findViewById(R.id.one)).setText(text);
((TextView) view.findViewById(R.id.two)).setText(text);
((TextView) view.findViewById(R.id.three)).setText(text);
((TextView) view.findViewById(R.id.four)).setText(text);
if (removeInLayout) {
LayoutParams lp = view.getLayoutParams();
addViewInLayout(view, 0, lp);
final int wms = MeasureSpec.makeMeasureSpec(r - l, MeasureSpec.EXACTLY);
final int hms = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
view.measure(wms, hms);
}
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
}
#Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
measureChild(view, widthMeasureSpec, heightMeasureSpec);
}
}
With the following xml layout as a child:
<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="84dp">
<TextView
android:id="#+id/one"
android:layout_width="100dp"
android:layout_height="84dp"
android:background="#FF00FF00"
tools:text="First View"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/one"
android:layout_toLeftOf="#+id/four"
android:layout_centerVertical="true"
android:layout_marginLeft="4dp"
android:paddingBottom="2dp"
android:orientation="vertical">
<TextView
android:id="#+id/two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="Second View"/>
<TextView
android:id="#+id/three"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="sans-light"
android:maxLines="3"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="12sp"
tools:text="Third View"/>
</LinearLayout>
<TextView
android:id="#+id/four"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="4dp"
android:layout_marginLeft="4dp"
tools:text="Fourth view"/>
</RelativeLayout>
Initially the view and its children draw just fine, and on the first click every view is redrawn as well. Any further clicks will only cause the views with id "one" and "four" to be redrawn. "two" and "three" becomes stuck.
If I remove the invalidate() from onLayout the views are never redrawn.
If I swap out the removeViewInLayout and addViewInLayout with detachViewFromParent and attachViewToParent the views are properly redrawn. If I remove the invalidate they are never redrawn.
Can anyone shed some light on what is happening? Should it not be possible to remove and re-add a view during the layout phase? And why isn't the fact that the child view is invalidated, although while detached, enough to cause a redraw?
I have uploaded a sample app to https://github.com/SimonVT/add-in-layout - click anywhere on the screen to fire the OnClickListener which increments the count variable and requests a layout.
I am using Horizontal Scroll View, dynamically i will add items in to that. if no. of items are more than displaying items on the screen i want to show image(arrow) at the edges ( like scroll view shows fading edges). How can i do it.
just look at below image, i want create like that.
this is the xml code
<HorizontalScrollView
android:layout_width="wrap_content"
android:scrollbars="none"
android:id="#+id/app_category"
android:layout_below="#+id/top_layout"
android:background="#drawable/minitopbar"
android:layout_height="30dp">
<LinearLayout
android:orientation="horizontal"
android:id="#+id/app_category_scroll_layout"
android:layout_width="wrap_content"
android:layout_height="fill_parent"/>
</HorizontalScrollView>
A. You have to create your own class, that extends HorizontalScrollView:
public class ExtendedHorizontalScrollView extends HorizontalScrollView {
private IScrollStateListener scrollStateListener;
public HorizontalScrollViewForMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public HorizontalScrollViewForMenu(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HorizontalScrollViewForMenu(Context context) {
super(context);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
prepare();
}
private void prepare() {
if (scrollStateListener != null) {
View content = this.getChildAt(0);
if (content.getLeft() >= 0)
scrollStateListener.onScrollMostLeft();
if (content.getLeft() < 0)
scrollStateListener.onScrollFromMostLeft();
if (content.getRight() <= getWidth())
scrollStateListener.onScrollMostRight();
if (content.getLeft() > getWidth())
scrollStateListener.onScrollFromMostRight();
}
}
#Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (scrollStateListener != null) {
if (l == 0)
scrollStateListener.onScrollMostLeft();
else if (oldl == 0)
scrollStateListener.onScrollFromMostLeft();
int mostRightL = this.getChildAt(0).getWidth() - getWidth();
if (l >= mostRightL)
scrollStateListener.onScrollMostRight();
if (oldl >= mostRightL && l < mostRightL)
scrollStateListener.onScrollFromMostRight();
}
}
public void setScrollStateListener(IScrollStateListener listener) {
scrollStateListener = listener;
}
public interface IScrollStateListener {
void onScrollMostLeft();
void onScrollFromMostLeft();
void onScrollMostRight();
void onScrollFromMostRight();
}
}
B. Use it defining of layout:
<LinearLayout
.....>
<ImageView
android:id="#+id/navigation_left"
..... />
<your.custom.view.package.ExtendedHorizontalScrollView
android:id="#+id/scroller"
android:layout_width="0px"
android:layout_weight="1"
android:fadingEdge="none"
....>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</your.custom.view.package.ExtendedHorizontalScrollView>
<ImageView
android:id="#+id/navigation_right"
..... />
</LinearLayout>
C. Add logic for disabling arrows when you can't scroll any more.
((ExtendedHorizontalScrollView)findViewById(R.id.scroller)).setScrollStateListener(new IScrollStateListener() {
public void onScrollMostRight() {
((View) scroller.getParent()).findViewById(R.id.navigation_right).setVisibility(View.INVISIBLE);
}
public void onScrollMostLeft() {
((View) scroller.getParent()).findViewById(R.id.navigation_left).setVisibility(View.INVISIBLE);
}
public void onScrollFromMostLeft() {
((View) scroller.getParent()).findViewById(R.id.navigation_left).setVisibility(View.VISIBLE);
}
public void onScrollFromMostRight() {
((View) scroller.getParent()).findViewById(R.id.navigation_right).setVisibility(View.VISIBLE);
}
});
An easy alternative is to make a scrollview without fading edges and then add the image with arrow below or on top of the scrollview.
Your xml something similar:
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:fadingEdge="none"
/>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<View
android:layout_height="6dp"
android:layout_width="fill_parent"
android:layout_alignParentBottom="true"
android:background="#drawable/background_effect"/>
</RelativeLayout>
</FrameLayout>