Rounded Background text like Instagram, ReplacementSpan not working as required(圆形背景文本(如 Instagram、ReplacementSpan 无法按要求工作))
问题描述
我试图在下面做一些类似于 Instagram 的事情 -
I was trying to do something similar to Instagram below -
但我想要像 Instagram 这样的曲线 -
But i want this curves like Instagram -
现在我又遇到了一个问题-当我键入时,.文本不会自动转到下一行,我必须按 return ,就像通常 editText 以固定宽度工作一样.(简而言之,multiline 不能与 ReplacementSpan 一起正常工作)
Now i am stuck in one more problem -
When i types,. text does not goes automatically to next line, I have to press return , like normally editText works in fixed width. (In short multiline is not working fine with ReplacementSpan)
下面是我所做的示例代码 -
Below is sample code for what i have done -
public class EditextActivity extends AppCompatActivity {
EditText edittext;
RoundedBackgroundSpan roundedBackgroundSpan;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.editext_screen);
edittext=(EditText)findViewById(R.id.edittext);
// edittext.setText("Hello My name is Karandeep Atwal.
Hii this is test");
roundedBackgroundSpan= new RoundedBackgroundSpan(Color.RED,Color.WHITE);
edittext.getText().setSpan(roundedBackgroundSpan, 0, edittext.getText().length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
public class RoundedBackgroundSpan extends ReplacementSpan implements LineHeightSpan {
private static final int CORNER_RADIUS = 15;
private static final int PADDING_X = 10;
private int mBackgroundColor;
private int mTextColor;
/**
* @param backgroundColor background color
* @param textColor text color
*/
public RoundedBackgroundSpan(int backgroundColor, int textColor) {
mBackgroundColor = backgroundColor;
mTextColor = textColor;
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
return (int) (PADDING_X + paint.measureText(text,start, end) + PADDING_X);
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
float width = paint.measureText(text,start, end);
RectF rect = new RectF(x, top, x + width + 2 * PADDING_X, bottom);
paint.setColor(mBackgroundColor);
canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, paint);
paint.setColor(mTextColor);
canvas.drawText(text, start, end, x + PADDING_X, y, paint);
}
@Override
public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fontMetricsInt) {
}
}
}
下面是我的xml -
Below is my xml -
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_gravity="center"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:padding="5dp"
android:background="@drawable/border"
android:id="@+id/edittext"
android:layout_centerInParent="true"
android:textColor="@android:color/black"
android:gravity="center"
android:hint="hi"
android:singleLine="false"
android:inputType="textMultiLine"
android:textSize="30sp"
android:maxWidth="100dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
以下是我使用 setSpan 键入时得到的结果 -
Below is what i am getting when i type using setSpan -
这是我想要的固定宽度的正常行为 -
This is normal behaviour for fixed width, that i want -
推荐答案
activity_main.xml
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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:background="@android:color/holo_purple"
tools:context="com.tttzof.demotext.MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Enter text"
android:textSize="30sp"
android:gravity="center"
android:textColor="@android:color/black"
android:background="@android:color/transparent"
android:layout_gravity="center"/>
</FrameLayout>
MainActivity.java
MainActivity.java
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.Spannable;
import android.text.TextWatcher;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText editText = (EditText) findViewById(R.id.editText);
int padding = dp(8);
int radius = dp(5);
final Object span = new BackgroundColorSpan(
Color.WHITE,
(float)padding,
(float) radius
);
editText.setShadowLayer(padding, 0f, 0f, 0);
editText.setPadding(padding, padding, padding, padding);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable s) {
s.setSpan(span, 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
});
}
private int dp(int value) {
return (int) (getResources().getDisplayMetrics().density * value + 0.5f);
}
}
BackgroundColorSpan.java
BackgroundColorSpan.java
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.text.style.LineBackgroundSpan;
public class BackgroundColorSpan implements LineBackgroundSpan {
private float padding;
private float radius;
private RectF rect = new RectF();
private Paint paint = new Paint();
private Paint paintStroke = new Paint();
private Path path = new Path();
private float prevWidth = -1f;
private float prevLeft = -1f;
private float prevRight = -1f;
private float prevBottom = -1f;
private float prevTop = -1f;
public BackgroundColorSpan(int backgroundColor,
float padding,
float radius) {
this.padding = padding;
this.radius = radius;
paint.setColor(backgroundColor);
//paintStroke.setStyle(Paint.Style.STROKE);
//paintStroke.setStrokeWidth(5f);
paintStroke.setColor(backgroundColor);
}
@Override
public void drawBackground(
final Canvas c,
final Paint p,
final int left,
final int right,
final int top,
final int baseline,
final int bottom,
final CharSequence text,
final int start,
final int end,
final int lnum) {
float width = p.measureText(text, start, end) + 2f * padding;
float shift = (right - width) / 2f;
rect.set(shift, top, right - shift, bottom);
if (lnum == 0) {
c.drawRoundRect(rect, radius, radius, paint);
} else {
path.reset();
float dr = width - prevWidth;
float diff = -Math.signum(dr) * Math.min(2f * radius, Math.abs(dr/2f))/2f;
path.moveTo(
prevLeft, prevBottom - radius
);
path.cubicTo(
prevLeft, prevBottom - radius,
prevLeft, rect.top,
prevLeft + diff, rect.top
);
path.lineTo(
rect.left - diff, rect.top
);
path.cubicTo(
rect.left - diff, rect.top,
rect.left, rect.top,
rect.left, rect.top + radius
);
path.lineTo(
rect.left, rect.bottom - radius
);
path.cubicTo(
rect.left, rect.bottom - radius,
rect.left, rect.bottom,
rect.left + radius, rect.bottom
);
path.lineTo(
rect.right - radius, rect.bottom
);
path.cubicTo(
rect.right - radius, rect.bottom,
rect.right, rect.bottom,
rect.right, rect.bottom - radius
);
path.lineTo(
rect.right, rect.top + radius
);
path.cubicTo(
rect.right, rect.top + radius,
rect.right, rect.top,
rect.right + diff, rect.top
);
path.lineTo(
prevRight - diff, rect.top
);
path.cubicTo(
prevRight - diff, rect.top,
prevRight, rect.top,
prevRight, prevBottom - radius
);
path.cubicTo(
prevRight, prevBottom - radius,
prevRight, prevBottom,
prevRight - radius, prevBottom
);
path.lineTo(
prevLeft + radius, prevBottom
);
path.cubicTo(
prevLeft + radius, prevBottom,
prevLeft, prevBottom,
prevLeft, rect.top - radius
);
c.drawPath(path, paintStroke);
}
prevWidth = width;
prevLeft = rect.left;
prevRight = rect.right;
prevBottom = rect.bottom;
prevTop = rect.top;
}
}
这篇关于圆形背景文本(如 Instagram、ReplacementSpan 无法按要求工作)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:圆形背景文本(如 Instagram、ReplacementSpan 无法按要
基础教程推荐
- Android:getLastKnownLocation(LocationManager.NETWORK_PROVIDER 2022-01-01
- iOS4 创建后台定时器 2022-01-01
- NSString intValue 不能用于检索电话号码 2022-01-01
- iPhone - 获取给定地点/时区的当前日期和时间并将其与同一地点的另一个日期/时间进行比较的正确方法 2022-01-01
- 通过重定向链接在 Google Play 中打开应用 2022-01-01
- navigator.geolocation.getCurrentPosition 在 Android 浏览器上 2022-01-01
- 如何从 logcat 中删除旧数据? 2022-01-01
- AdMob 广告未在模拟器中显示 2022-01-01
- Cocos2d iPhone 非矩形精灵触摸检测 2022-01-01
- libGDX 从精灵或纹理中获取像素颜色 2022-01-01
