Android动态RelativeLayout和子View的创建

发布于 2024-10-17 15:02:01 字数 2775 浏览 4 评论 0原文

在对这个话题提出了很多问题之后,我仍然没有完全解决这个问题。 最后,第一个图像视图总是被“覆盖”,或者更好地说是被另一个应该位于该视图右侧的视图重叠。

扩展RelativeLayout后,仅重写onLayout()方法来放置子视图就足够了吗? onLayout 方法是将所有子项放置在一次传递中还是为每个特定子项调用它?如果我想使用RelativeLayouts特定位置(RIGHT_OF、BELOW等),onLayout方法应该如何实现子位置?

在视图创建中,如何创建没有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());
 }
}

After numerous questions about this topic I still haven't fully solved the problem.
In the end the first imageview always gets "overwritten" or better said overlapped by another view which should go right of that view.

After extending RelativeLayout is it enough to only override onLayout() method for children view placement? Does onLayout method place all children in one pass or is it called for every specific child? How should that onLayout method implement child placement if I want to use RelativeLayouts specific placemnts (RIGHT_OF, BELOW, etc ...)

In view creation, how can I create a view without layoutparams, is it even possible?

EDIT: Ok I avoided using getWidth in any form and still get bad layout. Icons get first row mixed but full (5 icons), next row has 1 icon only and 2 are missing. At this point I'm quite frustrated because it's a stupid issue and I can't seem to find what's wrong, why doesn't official developer tutorial have more help on dynamic layouts and views?

Log.e from down says:
2: RIGHT OF 1
3: RIGHT OF 2
4: RIGHT OF 3
5: RIGHT OF 4
6: BELOW 1
7: RIGHT OF 6
8: RIGHT OF 7
9: RIGHT OF 8

That's the way it's supposed to be yet it doesn't work, I can't set relative position to layouts that should have been layed out?

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());
 }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜雨飘雪 2024-10-24 15:02:01

对于标准组件,如果您希望它们像往常一样布局组件,则实际上不需要重写 onLayout。如果您确实重写 onLayout 并且不调用 super.onLayout 那么您必须手动定位所有子级。

否则,只需使用添加了规则(BELOW、ABOVE等)的RelativeLayout.LayoutParams,并在添加视图时设置它 addView(youView, yourLayoutParamsInstance)

For standard components you don't really need to override onLayout, if you want for them to layout components as usual that is. If you do override onLayout and don't call super.onLayout then you must position all your children manually.

Otherwise, just use RelativeLayout.LayoutParams with added rules (BELOW, ABOVE, etc..) and set it when adding a view addView(youView, yourLayoutParamsInstance)

最初的梦 2024-10-24 15:02:01

RelativeLayout 中的大部分逻辑实际上发生在测量阶段,所以不,仅仅覆盖 onLayout 很可能是不够的。

如果你想扩展RelativeLayout,恐怕你必须习惯它的源代码,否则很难理解如何影响它的行为。不过,您确实应该考虑寻找另一种解决方案,因为您确实使用 RelativeLayout 选择了一个更复杂的类。

Most of the logic in RelativeLayout actually happens during the measurement phase, so no, just overriding onLayout is most likely not enough.

If you want to extend RelativeLayout, I'm afraid you'll have to get accustomed to it's source code, otherwise it'll be quite hard to understand how to influence it's behavior. You should really consider finding another solution though, since you really picked one of the more complex classes with RelativeLayout.

笨笨の傻瓜 2024-10-24 15:02:01

我最终所做的是停止使用相对参数来描述视图相对于其他视图的位置。相反,我自己做了所有的数学计算,并将所有内容放入 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);
 }
}

What I did in the end is quit using relative parameter to describe view's position relative to other view. Instead I did all the math myself and put everything in setMargins, hope that's is equally if not faster than using Relativelayouts methods to figure it out.

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);
 }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文