J'essaie d'afficher une ligne bleue à côté d'un bloc de texte, un peu comme ceci:
Voici mon code:
<TextView
Android:id="@+id/textView1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:drawableLeft="@drawable/blue_line" />
blue_line est un fichier jpg. un rectangle bleu. il affiche dans sa taille d'origine quel que soit le texte dans la vue texte. Comment puis-je ajuster sa hauteur dynamiquement en fonction de la hauteur du texte? comme le rendre plus court quand il y a peu de texte et plus quand il y a plus de texte ....
Vous pouvez essayer de le faire dans le code en définissant des limites pour l'image
textView1.getViewTreeObserver()
.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Drawable img = ActivityName.this.getContext().getResources().getDrawable(
R.drawable.blue_line);
img.setBounds(0, 0, img.getIntrinsicWidth() * textView1.getMeasuredHeight() / img.getIntrinsicHeight(), textView1.getMeasuredHeight());
textView1.setCompoundDrawables(img, null, null, null);
textView1.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
La meilleure façon de procéder consiste à envelopper votre dessin dans un fichier xml et de le définir comme dessin dans votre affichage texte comme suit:
Fichier XML dessinable:
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:scaleType="fitXY"
Android:src="@drawable/total_calories"/>
TextView en XML:
<TextView
Android:id="@+id/title_total_cal"
style="@style/title_stats_textview"
Android:drawableLeft="@drawable/total_calories_drawable"/>
Essayez comme ci-dessous ...
<RelativeLayout
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" >
<ImageView
Android:id="@+id/imageView"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:src="@drawable/btndr" />
<TextView
Android:id="@+id/textView1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_toRightOf="@+id/imageView" />
</RelativeLayout>
Simplement, gardez votre image comme dessin 9patch.
Vous pouvez ajouter Android:drawableLeft="@drawable/checkmark"
à votre textview. Vous pouvez également définir drawablePadding
pour que la vue texte soit organisée.
Android:drawableLeft="@drawable/button_icon"
Android:drawablePadding="2dip"
Voici le lien pour créer 9patch drawable
<TextView Android:text="@string/txtUserName"
Android:id="@+id/txtUserName"
Android:layout_width="160dip"
Android:layout_height="60dip"
Android:layout_gravity="center"
Android:drawableLeft="@drawable/button_icon"
Android:drawablePadding="2dip"
/>
Vous pouvez dessiner une ligne de la hauteur désirée sur une toile dessinable et la définir comme dessinable à gauche de votre TextView. regarde ça:
public class FullHeightLineDrawable extends Drawable {
private Paint mPaint;
private int mHeight;
public FullHeightLineDrawable(int height) {
mPaint = new Paint();
mPaint.setColor(CompatUtils.getColor(R.color.colorAccent));
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(15);
mHeight = height;
}
@Override
public void draw(Canvas canvas) {
canvas.drawLine(0, -mHeight, 0, mHeight, mPaint);
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return 0;
}
}
Usage:
final Drawable drawable = new FullHeightLineDrawable(getHeight());
mTextView.setTextColor(watchingColor);
mTextView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
J'ai créé une classe qui étend TextView
et redimensionne les éléments dessinables dans onPreDrawListener
.
public class MyTextView extends AppCompatTextView {
public MyTextView(Context context, AttributeSet attrs, int style) {
super(context, attrs, style);
fitCompoundDrawableToLineHeight();
}
private void fitCompoundDrawableToLineHeight() {
OnPreDraw.run(this, () -> {
final Drawable[] cd = getCompoundDrawables();
Arrays.stream(cd)
.filter(drawable -> drawable != null)
.forEach(d -> d.setBounds(0, 0, getLineHeight(), getLineHeight()));
setCompoundDrawables(cd[0], cd[1], cd[2], cd[3]);
});
}
}
// Convenience class that abstracts onPreDraw logic
public class OnPreDraw {
public static void run(View view, Runnable task) {
view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (!view.getViewTreeObserver().isAlive()) {
return true;
}
view.getViewTreeObserver().removeOnPreDrawListener(this);
task.run();
return true;
}
});
}
}
Malheureusement, setBounds ne fonctionnait pas pour moi, j'ai donc dû contourner le problème.
// Turn wanted drawable to bitmap
Drawable dr = getResources().getDrawable(R.drawable.somedrawable);
Bitmap bitmap = ((BitmapDrawable) dr).getBitmap();
// I had a square image with same height and width so I needed only TextView height (getLineHeight)
int size = textView1.getLineHeight();
Drawable d = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap, size, size, true));
textView1.setCompoundDrawables(d, null, null, null);
// Now we can set some spacing between text and image
textView1.setCompoundDrawablePadding(10);
Ce n'est pas la meilleure solution en termes de performances, car un nouveau bitmap est créé, mais fonctionne toujours.
Je résume cette méthode. Cela fonctionne quand le dessinable est à gauche du TextView, une mise à l'échelle dynamique. Si drawable est sur le côté droit, cette méthode ne fonctionne pas, vous devez donc comprendre pourquoi, mais vous pouvez simplement utiliser directement textView.setcompounddrawableswithintrinsicbounds()
avec la ressource Drawable de taille appropriée.
@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
public static void ajustCompoundDrawableSizeWithText(final TextView textView, final Drawable leftDrawable, final Drawable topDrawable, final Drawable rightDrawable, final Drawable bottomDrawable) {
textView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
if(leftDrawable != null){
leftDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
}
if(topDrawable != null){
topDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
}
if(rightDrawable != null){
rightDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
}
if(bottomDrawable != null){
bottomDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
}
textView.setCompoundDrawables(leftDrawable, topDrawable, rightDrawable, bottomDrawable);
textView.removeOnLayoutChangeListener(this);
}
});
}