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 layoutpa开发者_开发问答rams, 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());
}
}
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)
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
.
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);
}
}
精彩评论