Android динамическое создание RelativeLayout и дочерних представлений - PullRequest
0 голосов
/ 15 февраля 2011

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

После расширения RelativeLayout достаточно ли переопределить только метод onLayout () для размещения дочерних представлений?Помещает ли метод onLayout всех детей за один проход или он вызывается для каждого конкретного ребенка?Как этот метод onLayout должен реализовывать дочернее размещение, если я хочу использовать специальные метки RelativeLayouts (RIGHT_OF, BELOW и т. Д ...)

При создании представления, как я могу создать представление без layoutparams, возможно ли это?

РЕДАКТИРОВАТЬ: Хорошо, я избегал использовать getWidth в любой форме и все еще получаю плохой макет.Значки в первом ряду смешаны, но заполнены (5 значков), в следующем ряду только 1 значок, а 2 отсутствуют.На данный момент я очень разочарован, потому что это глупая проблема, и я не могу понять, в чем дело, почему официальное руководство для разработчиков не может больше помочь с динамическими макетами и представлениями?

Log.e отвниз говорит: 2: ПРАВО 1 3: ПРАВА 2 4: ПРАВА 3 5: ПРАВА 4 6: НИЖЕ 1 7: ПРАВА 6 8: ПРАВО 7 9: ПРАВА 8

Этокак это должно быть, но это не работает, я не могу установить относительное положение для макетов, которые должны были быть размещены?

private void loadResources() {

cursor = managedQuery(Browser.BOOKMARKS_URI, projection, selection,
null, SORT_BY_COLUMN + " " + SORT_ORDER);
this.startManagingCursor(cursor);

ImageView previousBookmark;

int idOfViewToTheLeft = 1;

if(cursor.moveToFirst()) {
    bookmarkCounter = 1;
    ByteArrayInputStream blobImage;

    int size = (int) scale * FAVICON_SIZE;
    int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
    int rowBookmarkCount = (int) (screenWidth/(size + scale*leftMargin));

    do{
       bookmark = new ImageView(this);
       bookmark.setId(bookmarkCounter++);
       bookmark.setBackgroundColor(Color.WHITE);

       blobImage = new ByteArrayInputStream(
               cursor.getBlob(cursor.getColumnIndex(BookmarkColumns.FAVICON)));

       bookmark.setImageDrawable(
               Drawable.createFromStream(blobImage, "" + bookmark.getId()));

       urls.put(bookmark.getId(),
               cursor.getString(
                        cursor.getColumnIndex(BookmarkColumns.URL)));

       bookmark.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent browserIntent = new Intent(
                        Intent.ACTION_VIEW, Uri.parse(urls.get(v.getId())));
                startActivity(browserIntent);
            }
        });

       lp = new RelativeLayout.LayoutParams(size, size);

       lp.topMargin = (int) (scale * topMargin);
       lp.leftMargin = (int) (scale * leftMargin);
       if(bookmark.getId() > 1) {
           previousBookmark = (ImageView) findViewById(bookmark.getId() - 1);

           if((bookmark.getId() % (rowBookmarkCount + 1)) != 0)
           {
               Log.e("" + bookmark.getId(), "RIGHT OF " + previousBookmark.getId());
               lp.addRule(RelativeLayout.RIGHT_OF, previousBookmark.getId());
           } else {
               Log.e("" + bookmark.getId(), "BELOW " + idOfViewToTheLeft);
               lp.addRule(RelativeLayout.BELOW, idOfViewToTheLeft);
               idOfViewToTheLeft = bookmark.getId();
           }
       }

       bookmarkLayout.addView(bookmark, lp);
    } while (cursor.moveToNext());
 }
}

Ответы [ 3 ]

0 голосов
/ 15 февраля 2011

Большая часть логики в RelativeLayout фактически происходит во время фазы измерения, поэтому нет, просто переопределение onLayout, скорее всего, недостаточно.

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

0 голосов
/ 17 февраля 2011

В конце концов я выполнил выход, используя относительный параметр, чтобы описать положение вида относительно другого вида. Вместо этого я выполнил всю математику сам и поместил все в setMargins, надеюсь, это будет одинаково, если не быстрее, чем использование методов Relativelayouts для выяснения этого.

private void loadResources() {

cursor = managedQuery(Browser.BOOKMARKS_URI, projection, selection,
null, SORT_BY_COLUMN + " " + SORT_ORDER);
this.startManagingCursor(cursor);

if(cursor.moveToFirst()) {
    bookmarkCounter = 0;
    ByteArrayInputStream blobImage;

    int leftMargin = (int) (scale * this.leftMargin);
    int topMargin = (int) (scale * this.topMargin);
    int size = (int) scale * FAVICON_SIZE;
    int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
    int rowBookmarkCount = (int) (screenWidth/(size + leftMargin));

    do{
       bookmark = new ImageView(this);
       bookmark.setId(bookmarkCounter++);
       bookmark.setBackgroundColor(Color.WHITE);

       blobImage = new ByteArrayInputStream(
               cursor.getBlob(cursor.getColumnIndex(BookmarkColumns.FAVICON)));

       bookmark.setImageDrawable(
               Drawable.createFromStream(blobImage, "" + bookmark.getId()));

       urls.put(bookmark.getId(),
               cursor.getString(
                        cursor.getColumnIndex(BookmarkColumns.URL)));

       bookmark.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent browserIntent = new Intent(
                        Intent.ACTION_VIEW, Uri.parse(urls.get(v.getId())));
                startActivity(browserIntent);
            }
        });

       lp = new RelativeLayout.LayoutParams(size, size);
       lp.setMargins(
               (int) (leftMargin + (bookmark.getId() % rowBookmarkCount) * (size + leftMargin)),
               (int) (topMargin + (bookmark.getId() / rowBookmarkCount) * (size + topMargin)),
               0, 0);
       bookmarkLayout.addView(bookmark, lp);
    } while (cursor.moveToNext());
    setContentView(scrollView);
 }
}
0 голосов
/ 15 февраля 2011

Для стандартных компонентов вам не нужно переопределять onLayout, если вы хотите, чтобы они размещали компоненты как обычно.Если вы переопределяете onLayout и не вызываете super.onLayout, вы должны вручную расположить всех своих детей.

В противном случае просто используйте RelativeLayout.LayoutParams с добавленными правилами (НИЖЕ, ВЫШЕ и т.при добавлении представления addView (youView, yourLayoutParamsInstance)

...