- 今天做一个儿歌MV,蓝湖设计稿如下图:
可以看到需要做描边效果,同时用到对应的字体,字体需要下载或者找设计师要。
原理是在红色字体后面再放一个白色的TextView
主要的坑是:红色的TextView和白色的TextView一定要用同一种字体,否则就会出现混乱
Demo效果如下:
字体目录如下:
- 对应的设置字体代码如下:
//可以单独放在一个工具类中
public static void setSongLyricFont(TextView textView) {
Typeface typeFace2 = Typeface.createFromAsset(yourApplication.getApplicationContext().getAssets(),
"fonts/SassoMonMed.ttf");
textView.setTypeface(typeFace2);
}
MainActivity代码如下:
public class MainActivity extends AppCompatActivity {
StrokeTextView stv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stv = findViewById(R.id.tv);
Typeface typeFace2 = Typeface.createFromAsset(this.getApplicationContext().getAssets(),
"fonts/SassoMonMed.ttf");
stv.setTypeface(typeFace2);
}
}
activity_main.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<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:background="#80000000"
tools:context=".MainActivity">
<com.zj.textviewdemo.StrokeTextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="The Wheels On The Bus"
android:textColor="#C81B8A"
android:textSize="22sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
StrokeTextView代码:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.TextView;
/*
* StrokeTextView的目标是给文字描边
* 实现方法是两个TextView叠加,只有描边的TextView为底,实体TextView叠加在上面
* 看上去文字就有个不同颜色的边框了
*/
public class StrokeTextView extends androidx.appcompat.widget.AppCompatTextView {
private TextView borderText = null;///用于描边的TextView
public StrokeTextView(Context context) {
super(context);
borderText = new TextView(context);
init();
}
public StrokeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
borderText = new TextView(context,attrs);
init();
}
public StrokeTextView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
borderText = new TextView(context,attrs,defStyle);
init();
}
public void init(){
TextPaint tp1 = borderText.getPaint();
tp1.setStrokeWidth(4); //设置描边宽度
tp1.setStyle(Style.STROKE); //对文字只描边
borderText.setTextColor(Color.parseColor("#ffffff")); //设置描边颜色
borderText.setGravity(getGravity());
Typeface typeFace2 = Typeface.createFromAsset(getContext().getApplicationContext().getAssets(),
"fonts/SassoMonMed.ttf");
borderText.setTypeface(typeFace2);
}
@Override
public void setLayoutParams (ViewGroup.LayoutParams params){
super.setLayoutParams(params);
borderText.setLayoutParams(params);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
CharSequence tt = borderText.getText();
//两个TextView上的文字必须一致
if(tt== null || !tt.equals(this.getText())){
borderText.setText(getText());
this.postInvalidate();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
borderText.measure(widthMeasureSpec, heightMeasureSpec);
}
protected void onLayout (boolean changed, int left, int top, int right, int bottom){
super.onLayout(changed, left, top, right, bottom);
borderText.layout(left, top, right, bottom);
}
@Override
protected void onDraw(Canvas canvas) {
borderText.draw(canvas);
super.onDraw(canvas);
}
}