Android: як намалювати межу для LinearLayout


197

У мене три файли. XML, функція малювання та основна діяльність. У мене є LinearLayoutXML-файл.

<LinearLayout android:orientation="horizontal"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:layout_weight="1">
    <LinearLayout android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:layout_weight="1"
                  android:background="#ef3"
                  android:id="@+id/img01"/>
    <LinearLayout android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:layout_weight="1"
                  android:background="#E8A2B4"
                  android:id="@+id/img02"/>
</LinearLayout>

Це функція малювання:

public class getBorder extends TextView {
    public getBorder(Context context) {
        super(context);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();

        paint.setColor(android.graphics.Color.RED);

        canvas.drawLine(0, 0, this.getWidth() - 1, 0, paint);
        canvas.drawLine(0, 0, 0, this.getHeight() - 1, paint);
        canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1,
            this.getHeight() - 1, paint);
        canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1,
            this.getHeight() - 1, paint);
    }
}

І це головна діяльність:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    final getBorder getBorder = new getBorder(this);
    final LinearLayout img01 = (LinearLayout) findViewById(R.id.img01);
    img01.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            getBorder.setWidth(100);
            getBorder.setHeight(100);
            img01.addView(getBorder);
        }
    });       
}

Програма могла б намалювати межу, але розмір не підходив LinearLayout. І коли я LinearLayoutзнову натискаю , програма виходить з ладу.

Інша справа, я хочу намалювати два кола в центрі LinearLayout, але як я міг розібрати координати центру?

Відповіді:


459

Вам справді потрібно це робити програмно?

Враховуючи назву: Ви можете використовувати ShapeDravable як андроїд: фон…

Наприклад, давайте визначимо res/drawable/my_custom_background.xmlяк:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
  <corners
      android:radius="2dp"
      android:topRightRadius="0dp"
      android:bottomRightRadius="0dp"
      android:bottomLeftRadius="0dp" />
  <stroke
      android:width="1dp"
      android:color="@android:color/white" />
</shape>

і визначте android: background = "@ dravable / my_custom_background".

Я не тестувався, але це має працювати.

Оновлення:

Я думаю, що краще використовувати потужність джерела ресурсу XML, якщо це відповідає вашим потребам. За допомогою проекту "з нуля" (для android-8) визначте res / layout / main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/border"
    android:padding="10dip" >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello World, SOnich"
        />
    [... more TextView ...]
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello World, SOnich"
        />
</LinearLayout>

і а res/drawable/border.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
   <stroke
        android:width="5dip"
        android:color="@android:color/white" />
</shape>

Повідомляється, що працює на пристрої пряників. Зауважте, що вам потрібно буде співвідносити android:paddingLinearLayout зі значенням android:widthформи / штриха. Будь ласка, не використовуйте @android:color/whiteу своїй остаточній заявці, а колір, визначений проектом.

Ви можете подати заявку android:background="@drawable/border" android:padding="10dip"до кожного LinearLayout із наданого зразка.

Що стосується інших ваших публікацій, пов’язаних із відображенням деяких кіл як фонового режиму LinearLayout, я граю з ресурсами " Inset / Scale / Layer" ( для отримання додаткової інформації див. "Drawable Resources" ), щоб отримати щось, що працює для відображення ідеальних кіл на фоні LinearLayout, але не вдалося на даний момент…

Ваша проблема чітко полягає у використанні getBorder.set{Width,Height}(100);. Чому ви робите це методом onClick?

Мені потрібна додаткова інформація, щоб не пропустити суть: чому ти це робиш програмно? Вам потрібна динамічна поведінка? Ваші вхідні малюнки - png або ShapeDrawable прийнятний? тощо.

Продовження (можливо, завтра і як тільки ви надасте більше точок щодо того, чого ви хочете досягти)…



@Renaud Чи є спосіб змінити колір межі проблематично?
користувач1940676

12
Невідомо, чому це було так, але коли я використовував це на LinearLayoutя, я отримав суцільне заповнення кольором межі, якщо я не додав до shapeелемента наступну дитину :<solid android:color="@android:color/transparent" />
dahvyd

2
Для мене це було те саме, що я повинен був додати, <solid android:color="@color/lighter_gray" />інакше я отримав чорний фон
Panciz

1
Цей метод прекрасно працює; однак, це створює двошаровий "Overdraw", який дуже погано працює, навіть якщо ви встановите фон на "null" або "transparent". Чи може хтось запропонувати спосіб виправити цю проблему?
Сем Рамезанлі

16

Розширюйте LinearLayout / RelativeLayout і використовуйте його прямо на XML

package com.pkg_name ;
...imports...
public class LinearLayoutOutlined extends LinearLayout {
    Paint paint;    

    public LinearLayoutOutlined(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        setWillNotDraw(false) ;
        paint = new Paint();
    }
    public LinearLayoutOutlined(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        setWillNotDraw(false) ;
        paint = new Paint();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        /*
        Paint fillPaint = paint;
        fillPaint.setARGB(255, 0, 255, 0);
        fillPaint.setStyle(Paint.Style.FILL);
        canvas.drawPaint(fillPaint) ;
        */

        Paint strokePaint = paint;
        strokePaint.setARGB(255, 255, 0, 0);
        strokePaint.setStyle(Paint.Style.STROKE);
        strokePaint.setStrokeWidth(2);  
        Rect r = canvas.getClipBounds() ;
        Rect outline = new Rect( 1,1,r.right-1, r.bottom-1) ;
        canvas.drawRect(outline, strokePaint) ;
    }

}

<?xml version="1.0" encoding="utf-8"?>

<com.pkg_name.LinearLayoutOutlined
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
    android:layout_width=...
    android:layout_height=...
   >
   ... your widgets here ...

</com.pkg_name.LinearLayoutOutlined>

34
Будь ласка, не розподіляйте пам'ять у onDraw()методі, створюйте об'єкти у init()методі, викликаному конструктором, та повторно використовуйте їх у onDraw()методі. Розподіл onDraw()(закликаний 60 разів на секунду) призводить до низької продуктивності, розряду акумулятора тощо
Louis CAD
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.