我正在开发一款安卓应用程序,将拥有类似以下图片的屏幕 -
请注意单元格之间的横幅广告。由于 GridView 不支持这样跨列,所以我不知道该怎么办。
请提供您能想到的任何建议。提前感谢。
我正在开发一款安卓应用程序,将拥有类似以下图片的屏幕 -
请注意单元格之间的横幅广告。由于 GridView 不支持这样跨列,所以我不知道该怎么办。
请提供您能想到的任何建议。提前感谢。
在我看来,使用带有GridLayoutManager的RecyclerView是最好的方法。只需为GridLayoutManager提供SpanSizeLookup即可确定每个位置的大小。例如,第一个位置需要占据整行。
//Two items in a row
int spanCount = 2;
GridLayoutManager manager = new GridLayoutManager(getActivity(),spanCount);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return (position == 0 ? spanCount : 1);
}
});
在您的适配器中提供两种类型的项目 - 常规项目和广告项目
最好通过ItemDecoration设置项目填充。
如果需要,我可以提供更多代码。
我想我可以给你举一些代码的例子...首先,我添加了AsymmetricGridView。
compile 'com.felipecsl.asymmetricgridview:library:2.0.1'
ListAdapter ia = new PreviewsAdapter(mContext, currentPreviews).setAdsWidth(numRows);
gridListView.setRequestedColumnWidth(Utils.dpToPx(mContext, 80));
gridListView.setAllowReordering(true);
AsymmetricGridViewAdapter asymmetricAdapter =
new AsymmetricGridViewAdapter<>(mContext, gridListView, ia);
gridListView.setAdapter(asymmetricAdapter);
gridListView.setOnItemClickListener(gridviewOnItemClickListener);
Display display = mContext.getWindowManager().getDefaultDisplay();
Point size = new Point();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
display.getSize(size);
} else {
size.set(display.getWidth(), display.getHeight());
}
final int mSize;
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
mSize = Math.min(size.x, size.y);
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
mSize = Math.max(size.x, size.y) - Math.min(size.x, size.y);
} else {
mSize = Math.min(size.x, size.y);
}
int numRows = Math.round((float) mSize / (float) Utils.dpToPx(mContext, 100));
// 80 width cell item + 20 padding
在适配器PreviewsAdapter中的所有魔法都在继承BaseAdapter的基础上实现。
确定广告位置。我想要在中间。
adsId = currentPreviews.size() / 2;
伪造多个条目。我们的条目数 + 广告
public int getCount() {
return currentPreviews.size() + 1;
}
public Object getItem(int position) {
if(adsId != position) {
if(position >= adsId) {
position-=1;
}
return currentPreviews.get(position);
} else {
return new AdsItem(this.numRows, 1);
}
}
我们的对象必须实现AsymmetricItem接口。广告也是如此。以下是一个广告对象类的示例。
public class AdsItem implements AsymmetricItem {
private final int width;
private final int height;
public AdsItem(int adsWidth, int adsHeight) {
width = adsWidth;
height = adsHeight;
}
@Override
public int getColumnSpan() {
return width;
}
@Override
public int getRowSpan() {
return height;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
}
}
getRowSpan和getColumnSpan确定单元格中对象视图的宽度和高度。
以下是获取视图的方法:
public View getView(int position, View convertView, ViewGroup parent) {
if(adsId != position) {
ImageView imageView;
if (convertView == null) {
imageView = new SquareImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.MATCH_PARENT, GridView.LayoutParams.MATCH_PARENT));
imageView.setPadding(10, 10, 10, 10);
} else {
imageView = (SquareImageView) convertView;
}
AvatarPart ap = (AvatarPart) getItem(position);
Bitmap b = imgs.get(ap.getFile());
imageView.setImageBitmap(b);
imageView.invalidate();
return imageView;
} else {
String adId = mContext.getResources().getString(R.string.add_id);
AdView mAdView = new AdView(mContext);
mAdView.setPadding(0, 15, 0, 15);
mAdView.setAdSize(AdSize.BANNER);
mAdView.setAdUnitId(adId);
AdRequest adRequest = new AdRequest.Builder()
.build();
if(mAdView.getAdSize() != null )
mAdView.loadAd(adRequest);
return mAdView;
}
}
但我对这行代码不太确定:
imageView = (SquareImageView) convertView;
我不知道如何获取 AdView。但是目前它没有出现问题:D
要处理点击事件需要编写另一个方法。
public AvatarPart getItemWithoutAds(int position) {
if(position == adsId) return null;
if(position >= adsId) {
position-=1;
}
return currentPreviews.get(position);
}
这段代码并不是最优美的,但它可以正常工作。结果如下图所示:
你需要为Gridview Adapter创建两个布局。一个用于显示你想要展示的内容,另一个用于 adView,同时在创建视图时交替使用这两个布局。
查看此链接以获取更多想法。