2016-02-10 3 views
0

Я ищу макета вроде L Clock:Идеальный круг вокруг TextViews

Более конкретно, 7 писем с кругами вокруг него. Я действительно хочу сделать макет с 7 кругами одинакового размера (на любом устройстве) рядом с другим (по горизонтали).

Что я пытался сделать: Чтобы сделать LinearLayout с ориентацией = горизонтальной. Чтобы сделать «овальную форму» применительно к 7 TextViews внутри этого LinearLayout. Затем я накладываю на каждый TextView вес = 1.

Это не сработало (и я не был уверен, было ли это хорошей идеей, так как я слышал, что мы должны избегать использования «веса»), и я попытался создать пользовательское текстовое представление и переопределить метод onMeasure.

Класс

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    int height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); 
    setMeasuredDimension(height, height); 
} 

Layout

<br.com.sibela.testtextviewsamesize.component.RoundTextView 
    android:layout_margin="10dp" 
    android:textAlignment="center" 
    android:layout_weight="1" 
    android:background="@drawable/circular_textview" 
    android:text="T" 
    android:layout_gravity="center" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" /> 

Форма:

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="oval"> 
    <solid android:color="#4488FF" /> 
</shape> 

Теперь мне нужно знать две вещи:

1) Как сделать 7-закругленными круги с одинаковым размером ocup ping всю ширину экрана?

2) Должен ли я действительно избегать использования веса?

UPDATE:

XML:

<?xml version="1.0" encoding="utf-8"?> 
<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="wrap_content" 
    android:orientation="horizontal" 
    tools:context=".MainActivity"> 

    <Button 
     android:id="@+id/btn1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/circular_textview" 
     android:minHeight="1dp" 
     android:minWidth="1dp" 
     android:text="S" /> 

    <Button 
     android:id="@+id/btn2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/circular_textview" 
     android:minHeight="1dp" 
     android:minWidth="1dp" 
     android:text="M" /> 

    <Button 
     android:id="@+id/btn3" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/circular_textview" 
     android:minHeight="1dp" 
     android:minWidth="1dp" 
     android:text="T" /> 

    <Button 
     android:id="@+id/btn4" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/circular_textview" 
     android:minHeight="1dp" 
     android:minWidth="1dp" 
     android:text="W" /> 

    <Button 
     android:id="@+id/btn5" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/circular_textview" 
     android:minHeight="1dp" 
     android:minWidth="1dp" 
     android:text="T" /> 

    <Button 
     android:id="@+id/btn6" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/circular_textview" 
     android:minHeight="1dp" 
     android:minWidth="1dp" 
     android:text="F" /> 

    <Button 
     android:id="@+id/btn7" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/circular_textview" 
     android:minHeight="1dp" 
     android:minWidth="1dp" 
     android:text="S" /> 

</LinearLayout> 

Класс:

package br.com.sibela.testtextviewsamesize; 

import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.DisplayMetrics; 
import android.widget.Button; 

public class MainActivity extends AppCompatActivity { 

    Button btn1; 
    Button btn2; 
    Button btn3; 
    Button btn4; 
    Button btn5; 
    Button btn6; 
    Button btn7; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     btn1 = (Button) findViewById(R.id.btn1); 
     btn2 = (Button) findViewById(R.id.btn2); 
     btn3 = (Button) findViewById(R.id.btn3); 
     btn4 = (Button) findViewById(R.id.btn4); 
     btn5 = (Button) findViewById(R.id.btn5); 
     btn6 = (Button) findViewById(R.id.btn6); 
     btn7 = (Button) findViewById(R.id.btn7); 

     DisplayMetrics display = this.getResources().getDisplayMetrics(); 
     int width = (display.widthPixels)/7; 
     btn1.setWidth(width); 
     btn2.setWidth(width); 
     btn3.setWidth(width); 
     btn4.setWidth(width); 
     btn5.setWidth(width); 
     btn6.setWidth(width); 
     btn7.setWidth(width); 

     btn1.setHeight(width); 
     btn2.setHeight(width); 
     btn3.setHeight(width); 
     btn4.setHeight(width); 
     btn5.setHeight(width); 
     btn6.setHeight(width); 
     btn7.setHeight(width); 
    } 
} 

Форма:

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="oval"> 
    <solid android:color="#4488FF" /> 
</shape> 
+1

Нет причин, чтобы избежать веса. Используйте его, когда вам это нужно. Просто не кладите вес туда, где он не нужен, и старайтесь избегать вложенных весов, это дорогостоящие вычисления. –

+1

Для остальных определений не получилось. Если вам нужен круг, овальная форма не будет работать, если ширина и высота представления не будут одинаковыми. И если вы используете вес, ширина представления должна быть равна 0dp, а не wrap_content. –

+0

Использование Java позволяет получить ширину экрана пользователя. Затем разделите его на 7 [Общее число TextViews] и установите результирующее значение как Height of TextViews. Таким образом, ширина и высота будут одинаковыми. Также в соответствии с комментарием чуть выше моего, setwidth до 0dp при использовании веса в горизонтальном LinearLayout [И установите Height в 0dp при использовании Vertical LinearLayout]. Также имейте в виду, чтобы учитывать прокладки и поля при поиске высоты на Java. –

ответ

0

Вы в течение многих неприятностей, если вы решите подкласс TextView. TextView многое делает, но здесь он не нужен.

Вместо этого сделать custom view, использовать его один раз для каждой буквы, а в OnDraw для зрения, просто нарисуйте круг и письмо в Canvas, как вы хотите, чтобы они появились (с помощью drawText и drawCircle). Вы все равно можете упорядочить свои пользовательские представления любым способом, но вам не нужно будет догадываться, что TextView будет делать с вашим текстом, потому что вместо этого вы будете управлять его рендерингом.

Это будет лишняя работа спереди, чтобы сделать пользовательский вид, но в конечном итоге вы сэкономите массу неприятностей.

+0

Мне жаль, что мне так много нужно было ответить, но я попытался понять, как это сделать, как вы мне сказали, но я не мог. Я пробовал некоторые новые вещи, и я почти получил то, что хотел получить размер экрана, разделив его на семь и установив его как по ширине, так и по высоте на мои элементы, но мое решение все еще неполно, потому что теперь я не могу поместить их на поля или иначе это не приведет к экрану. Не могли бы вы привести пример о том, как это сделать так, как вы сказали мне? Я обновлю свой вопрос и покажу вам, что я сделал (PS: я изменил свой TextViews на кнопки) – LeonardoSibela

0

Один из вариантов, получите 7 изображений, и вы можете использовать этот класс CircleImageView, чтобы сделать его круглым.

public class CircleImageView extends ImageView { 

    private static final ImageView.ScaleType SCALE_TYPE = ImageView.ScaleType.CENTER_CROP; 

    private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; 
    private static final int COLORDRAWABLE_DIMENSION = 2; 

    private static final int DEFAULT_BORDER_WIDTH = 0; 
    private static final int DEFAULT_BORDER_COLOR = Color.BLACK; 
    private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT; 
    private static final boolean DEFAULT_BORDER_OVERLAY = false; 

    private final RectF mDrawableRect = new RectF(); 
    private final RectF mBorderRect = new RectF(); 

    private final Matrix mShaderMatrix = new Matrix(); 
    private final Paint mBitmapPaint = new Paint(); 
    private final Paint mBorderPaint = new Paint(); 
    private final Paint mFillPaint = new Paint(); 

    private int mBorderColor = DEFAULT_BORDER_COLOR; 
    private int mBorderWidth = DEFAULT_BORDER_WIDTH; 
    private int mFillColor = DEFAULT_FILL_COLOR; 

    private Bitmap mBitmap; 
    private BitmapShader mBitmapShader; 
    private int mBitmapWidth; 
    private int mBitmapHeight; 

    private float mDrawableRadius; 
    private float mBorderRadius; 

    private ColorFilter mColorFilter; 

    private boolean mReady; 
    private boolean mSetupPending; 
    private boolean mBorderOverlay; 

    public CircleImageView(Context context) { 
     super(context); 

     init(); 
    } 

    public CircleImageView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public CircleImageView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 

     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); 

     mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH); 
     mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR); 
     mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY); 
     mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR); 

     a.recycle(); 

     init(); 
    } 

    private void init() { 
     super.setScaleType(SCALE_TYPE); 
     mReady = true; 

     if (mSetupPending) { 
      setup(); 
      mSetupPending = false; 
     } 
    } 

    @Override 
    public ScaleType getScaleType() { 
     return SCALE_TYPE; 
    } 

    @Override 
    public void setScaleType(ScaleType scaleType) { 
     if (scaleType != SCALE_TYPE) { 
      throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType)); 
     } 
    } 

    @Override 
    public void setAdjustViewBounds(boolean adjustViewBounds) { 
     if (adjustViewBounds) { 
      throw new IllegalArgumentException("adjustViewBounds not supported."); 
     } 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     if (mBitmap == null) { 
      return; 
     } 

     if (mFillColor != Color.TRANSPARENT) { 
      canvas.drawCircle(getWidth()/2.0f, getHeight()/2.0f, mDrawableRadius, mFillPaint); 
     } 
     canvas.drawCircle(getWidth()/2.0f, getHeight()/2.0f, mDrawableRadius, mBitmapPaint); 
     if (mBorderWidth != 0) { 
      canvas.drawCircle(getWidth()/2.0f, getHeight()/2.0f, mBorderRadius, mBorderPaint); 
     } 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     setup(); 
    } 

    public int getBorderColor() { 
     return mBorderColor; 
    } 

    public void setBorderColor(@ColorInt int borderColor) { 
     if (borderColor == mBorderColor) { 
      return; 
     } 

     mBorderColor = borderColor; 
     mBorderPaint.setColor(mBorderColor); 
     invalidate(); 
    } 

    public void setBorderColorResource(@ColorRes int borderColorRes) { 
     setBorderColor(getContext().getResources().getColor(borderColorRes)); 
    } 

    public int getFillColor() { 
     return mFillColor; 
    } 

    public void setFillColor(@ColorInt int fillColor) { 
     if (fillColor == mFillColor) { 
      return; 
     } 

     mFillColor = fillColor; 
     mFillPaint.setColor(fillColor); 
     invalidate(); 
    } 

    public void setFillColorResource(@ColorRes int fillColorRes) { 
     setFillColor(getContext().getResources().getColor(fillColorRes)); 
    } 

    public int getBorderWidth() { 
     return mBorderWidth; 
    } 

    public void setBorderWidth(int borderWidth) { 
     if (borderWidth == mBorderWidth) { 
      return; 
     } 

     mBorderWidth = borderWidth; 
     setup(); 
    } 

    public boolean isBorderOverlay() { 
     return mBorderOverlay; 
    } 

    public void setBorderOverlay(boolean borderOverlay) { 
     if (borderOverlay == mBorderOverlay) { 
      return; 
     } 

     mBorderOverlay = borderOverlay; 
     setup(); 
    } 

    @Override 
    public void setImageBitmap(Bitmap bm) { 
     super.setImageBitmap(bm); 
     mBitmap = bm; 
     setup(); 
    } 

    @Override 
    public void setImageDrawable(Drawable drawable) { 
     super.setImageDrawable(drawable); 
     mBitmap = getBitmapFromDrawable(drawable); 
     setup(); 
    } 

    @Override 
    public void setImageResource(@DrawableRes int resId) { 
     super.setImageResource(resId); 
     mBitmap = getBitmapFromDrawable(getDrawable()); 
     setup(); 
    } 

    @Override 
    public void setImageURI(Uri uri) { 
     super.setImageURI(uri); 
     mBitmap = uri != null ? getBitmapFromDrawable(getDrawable()) : null; 
     setup(); 
    } 

    @Override 
    public void setColorFilter(ColorFilter cf) { 
     if (cf == mColorFilter) { 
      return; 
     } 

     mColorFilter = cf; 
     mBitmapPaint.setColorFilter(mColorFilter); 
     invalidate(); 
    } 

    private Bitmap getBitmapFromDrawable(Drawable drawable) { 
     if (drawable == null) { 
      return null; 
     } 

     if (drawable instanceof BitmapDrawable) { 
      return ((BitmapDrawable) drawable).getBitmap(); 
     } 

     try { 
      Bitmap bitmap; 

      if (drawable instanceof ColorDrawable) { 
       bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); 
      } else { 
       bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); 
      } 

      Canvas canvas = new Canvas(bitmap); 
      drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); 
      drawable.draw(canvas); 
      return bitmap; 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 

    private void setup() { 
     if (!mReady) { 
      mSetupPending = true; 
      return; 
     } 

     if (getWidth() == 0 && getHeight() == 0) { 
      return; 
     } 

     if (mBitmap == null) { 
      invalidate(); 
      return; 
     } 

     mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 

     mBitmapPaint.setAntiAlias(true); 
     mBitmapPaint.setShader(mBitmapShader); 

     mBorderPaint.setStyle(Paint.Style.STROKE); 
     mBorderPaint.setAntiAlias(true); 
     mBorderPaint.setColor(mBorderColor); 
     mBorderPaint.setStrokeWidth(mBorderWidth); 

     mFillPaint.setStyle(Paint.Style.FILL); 
     mFillPaint.setAntiAlias(true); 
     mFillPaint.setColor(mFillColor); 

     mBitmapHeight = mBitmap.getHeight(); 
     mBitmapWidth = mBitmap.getWidth(); 

     mBorderRect.set(0, 0, getWidth(), getHeight()); 
     mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth)/2.0f, (mBorderRect.width() - mBorderWidth)/2.0f); 

     mDrawableRect.set(mBorderRect); 
     if (!mBorderOverlay) { 
      mDrawableRect.inset(mBorderWidth, mBorderWidth); 
     } 
     mDrawableRadius = Math.min(mDrawableRect.height()/2.0f, mDrawableRect.width()/2.0f); 

     updateShaderMatrix(); 
     invalidate(); 
    } 

    private void updateShaderMatrix() { 
     float scale; 
     float dx = 0; 
     float dy = 0; 

     mShaderMatrix.set(null); 

     if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) { 
      scale = mDrawableRect.height()/(float) mBitmapHeight; 
      dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f; 
     } else { 
      scale = mDrawableRect.width()/(float) mBitmapWidth; 
      dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f; 
     } 

     mShaderMatrix.setScale(scale, scale); 
     mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top); 

     mBitmapShader.setLocalMatrix(mShaderMatrix); 
    } 

} 

Вместо ImageView использование CircleImageView как в Java и XML.

Надеюсь, это поможет!:)