接入文档 -- 穿山甲 -- 模板渲染信息流(RecyclerView)

接入文档 --> 穿山甲 – 模板渲染信息流(RecyclerView)

因为自渲染信息流广告: 已回收,不再提供创建

因此使用模板渲染信息流广告, 官方接入文档中模板信息流广告使用ListView,本文采用RecyclerView

XinXiLiu.java

public class XinXiLiu extends AppCompatActivity {

    private RecyclerView mRecyclerview;
    private TTAdNative mTTAdNative;
    private List<TTNativeExpressAd> mData;
    Context mContext;
    private MyAdapter myAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_xin_xi_liu);

        initAD();
        initView();
    }
    

    private void initAD() {
        //step1:初始化sdk
        TTAdManagerHolder.init(this);
        TTAdManager ttAdManager = TTAdManagerHolder.get();
        //step2:创建TTAdNative对象,用于调用广告请求接口
        mTTAdNative = ttAdManager.createAdNative(this);
        //step3:(可选,强烈建议在合适的时机调用):申请部分权限,如read_phone_state,防止获取不了imei时候,下载类广告没有填充的问题。
        TTAdManagerHolder.get().requestPermissionIfNecessary(this);
        //
        mData = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            mData.add(null);
        }
    }

    private void initView() {
        mContext = this;
        mRecyclerview = (RecyclerView) findViewById(R.id.recyclerview);
        mRecyclerview.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        myAdapter = new MyAdapter(mContext, mData);
        mRecyclerview.setAdapter(myAdapter);
        loadListAd();
    }

    private void loadListAd() {
        float expressViewWidth = 350;
        float expressViewHeight = 350;
        try {
            expressViewHeight = Float.parseFloat("0");
        } catch (Exception e) {
            expressViewHeight = 0; //高度设置为0,则高度会自适应
        }
        //step4:创建feed广告请求类型参数AdSlot,具体参数含义参考文档
        AdSlot adSlot = new AdSlot.Builder()
                .setCodeId("945***750")//自己的广告id
                .setExpressViewAcceptedSize(expressViewWidth, expressViewHeight) //期望模板广告view的size,单位dp
                .setAdCount(3) //请求广告数量为1到3条
                .build();
        //step5:请求广告,调用feed广告异步请求接口,加载到广告后,拿到广告素材自定义渲染
        mTTAdNative.loadNativeExpressAd(adSlot, new TTAdNative.NativeExpressAdListener() {
            @Override
            public void onError(int code, String message) {
                if (mRecyclerview != null) {

                }
            }

            @Override
            public void onNativeExpressAdLoad(List<TTNativeExpressAd> ads) {
                if (mRecyclerview != null) {

                }
                if (ads == null || ads.isEmpty()) {
                    return;
                }
                bindAdListener(ads);
            }
        });
    }

    private void bindAdListener(final List<TTNativeExpressAd> ads) {
//        final int count = mData.size();
        int i = 1;
        for (TTNativeExpressAd ad : ads) {
            final TTNativeExpressAd adTmp = ad;
            //设置广告位置
            mData.set(i, adTmp);
            i += 3;
            myAdapter.notifyDataSetChanged();

            adTmp.setExpressInteractionListener(new TTNativeExpressAd.ExpressAdInteractionListener() {
                @Override
                public void onAdClicked(View view, int type) {
                    TToast.show(XinXiLiu.this, "广告被点击");
                }

                @Override
                public void onAdShow(View view, int type) {
                    TToast.show(XinXiLiu.this, "广告展示");
                }

                @Override
                public void onRenderFail(View view, String msg, int code) {
                    TToast.show(XinXiLiu.this, msg + " code:" + code);
                }

                @Override
                public void onRenderSuccess(View view, float width, float height) {
                    //返回view的宽高 单位 dp
                    TToast.show(XinXiLiu.this, "渲染成功");
                }
            });
            ad.render();

        }

    }

}

activity_xin_xi_liu.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/darker_gray"
    tools:context=".xinxiliu.XinXiLiu">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.8" />

</androidx.constraintlayout.widget.ConstraintLayout>


MyAdapter.java

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int ITEM_VIEW_TYPE_NORMAL = 0;
    private static final int ITEM_VIEW_TYPE_GROUP_PIC_AD = 1;
    private static final int ITEM_VIEW_TYPE_SMALL_PIC_AD = 2;
    private static final int ITEM_VIEW_TYPE_LARGE_PIC_AD = 3;
    private static final int ITEM_VIEW_TYPE_VIDEO = 4;
    private static final int ITEM_VIEW_TYPE_VERTICAL_IMG = 5;//竖版图片
    private static final int ITEM_VIEW_TYPE_VIDEO_VERTICAL = 6;//竖版视频

    private Map<AdViewHolder, TTAppDownloadListener> mTTAppDownloadListenerMap = new WeakHashMap<>();


    Context mContext;
    private List<TTNativeExpressAd> mData;

    public MyAdapter(Context context, List<TTNativeExpressAd> mData) {
        this.mContext = context;
        this.mData = mData;
    }


    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        switch (viewType) {
            case ITEM_VIEW_TYPE_SMALL_PIC_AD:
            case ITEM_VIEW_TYPE_LARGE_PIC_AD:
            case ITEM_VIEW_TYPE_GROUP_PIC_AD:
            case ITEM_VIEW_TYPE_VERTICAL_IMG:
            case ITEM_VIEW_TYPE_VIDEO:
            case ITEM_VIEW_TYPE_VIDEO_VERTICAL:
                return new AdViewHolder(layoutInflater.inflate(R.layout.listitem_ad_native_express, parent, false));
            default:
                return new MyViewHolder(layoutInflater.inflate(R.layout.item, parent, false));
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if(holder instanceof AdViewHolder){
            try{
                AdViewHolder adViewHolder = (AdViewHolder) holder;
                bindData(adViewHolder, mData.get(position));
                if (adViewHolder.videoView != null) {
                    View video = mData.get(position).getExpressAdView();
                    if (video != null) {
                        adViewHolder.videoView.removeAllViews();
                        if (video.getParent() == null) {
                            adViewHolder.videoView.addView(video);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else if(holder instanceof MyViewHolder){
            MyViewHolder myViewHolder = (MyViewHolder) holder;
            myViewHolder.textView.setText("=======> " + position);
        }
    }

    public TTNativeExpressAd getItemAd(int i) {
        return mData.get(i);
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    @Override
    public int getItemViewType(int position) {
        TTNativeExpressAd ad = getItemAd(position);
        if (ad == null) {
            return ITEM_VIEW_TYPE_NORMAL;
        } else if (ad.getImageMode() == TTAdConstant.IMAGE_MODE_SMALL_IMG) {
            return ITEM_VIEW_TYPE_SMALL_PIC_AD;
        } else if (ad.getImageMode() == TTAdConstant.IMAGE_MODE_LARGE_IMG) {
            return ITEM_VIEW_TYPE_LARGE_PIC_AD;
        } else if (ad.getImageMode() == TTAdConstant.IMAGE_MODE_GROUP_IMG) {
            return ITEM_VIEW_TYPE_GROUP_PIC_AD;
        } else if (ad.getImageMode() == TTAdConstant.IMAGE_MODE_VIDEO) {
            return ITEM_VIEW_TYPE_VIDEO;
        } else if (ad.getImageMode() == TTAdConstant.IMAGE_MODE_VERTICAL_IMG) {
            return ITEM_VIEW_TYPE_VERTICAL_IMG;
        } else if (ad.getImageMode() == TTAdConstant.IMAGE_MODE_VIDEO_VERTICAL) {
            return ITEM_VIEW_TYPE_VIDEO_VERTICAL;
        } else {
            TToast.show(mContext, "图片展示样式错误");
            return ITEM_VIEW_TYPE_NORMAL;
        }
    }

    static class MyViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.textView);
        }
    }

    static class AdViewHolder extends RecyclerView.ViewHolder {
        FrameLayout videoView;

        public AdViewHolder(@NonNull View itemView) {
            super(itemView);
            videoView = itemView.findViewById(R.id.iv_listitem_express);
        }
    }

    private void bindData(final AdViewHolder adViewHolder, TTNativeExpressAd ad) {
        //设置dislike弹窗
        bindDislike(ad, false);
        switch (ad.getInteractionType()) {
            case TTAdConstant.INTERACTION_TYPE_DOWNLOAD:
                bindDownloadListener(adViewHolder, ad);
                break;
        }
    }

    /**
     * 设置广告的不喜欢,注意:强烈建议设置该逻辑,如果不设置dislike处理逻辑,则模板广告中的 dislike区域不响应dislike事件。
     *
     * @param ad
     * @param customStyle 是否自定义样式,true:样式自定义
     */
    private void bindDislike(final TTNativeExpressAd ad, boolean customStyle) {
        if (customStyle) {
            //使用自定义样式
            DislikeInfo dislikeInfo = ad.getDislikeInfo();
            if (dislikeInfo == null || dislikeInfo.getFilterWords() == null || dislikeInfo.getFilterWords().isEmpty()) {
                return;
            }
            final DislikeDialog dislikeDialog = new DislikeDialog(mContext, dislikeInfo);
            dislikeDialog.setOnDislikeItemClick(new DislikeDialog.OnDislikeItemClick() {
                @Override
                public void onItemClick(FilterWord filterWord) {
                    //屏蔽广告
                    TToast.show(mContext, "点击 " + filterWord.getName());
                    //用户选择不喜欢原因后,移除广告展示
                    mData.remove(ad);
                    notifyDataSetChanged();
                }
            });
            dislikeDialog.setOnPersonalizationPromptClick(new DislikeDialog.OnPersonalizationPromptClick() {
                @Override
                public void onClick(PersonalizationPrompt personalizationPrompt) {
                    TToast.show(mContext, "点击了为什么看到此广告");
                }
            });
            ad.setDislikeDialog(dislikeDialog);
            return;
        }
        //使用默认模板中默认dislike弹出样式
        ad.setDislikeCallback((Activity) mContext, new TTAdDislike.DislikeInteractionCallback() {
            @Override
            public void onShow() {

            }

            @Override
            public void onSelected(int position, String value) {
                TToast.show(mContext, "点击 " + value);
                //用户选择不喜欢原因后,移除广告展示
                mData.remove(ad);
                notifyDataSetChanged();
            }

            @Override
            public void onCancel() {
                TToast.show(mContext, "点击取消 ");
            }

            @Override
            public void onRefuse() {

            }
        });
    }

    private void bindDownloadListener(final AdViewHolder adViewHolder, TTNativeExpressAd ad) {
        TTAppDownloadListener downloadListener = new TTAppDownloadListener() {
            private boolean mHasShowDownloadActive = false;

            @Override
            public void onIdle() {
                if (!isValid()) {
                    return;
                }
                TToast.show(mContext, "点击广告开始下载");
            }

            @SuppressLint("SetTextI18n")
            @Override
            public void onDownloadActive(long totalBytes, long currBytes, String fileName, String appName) {
                if (!isValid()) {
                    return;
                }
                if (!mHasShowDownloadActive) {
                    mHasShowDownloadActive = true;
                    TToast.show(mContext, appName + " 下载中,点击暂停", Toast.LENGTH_LONG);
                }
            }

            @SuppressLint("SetTextI18n")
            @Override
            public void onDownloadPaused(long totalBytes, long currBytes, String fileName, String appName) {
                if (!isValid()) {
                    return;
                }
                TToast.show(mContext, appName + " 下载暂停", Toast.LENGTH_LONG);

            }

            @Override
            public void onDownloadFailed(long totalBytes, long currBytes, String fileName, String appName) {
                if (!isValid()) {
                    return;
                }
                TToast.show(mContext, appName + " 下载失败,重新下载", Toast.LENGTH_LONG);
            }

            @Override
            public void onInstalled(String fileName, String appName) {
                if (!isValid()) {
                    return;
                }
                TToast.show(mContext, appName + " 安装完成,点击打开", Toast.LENGTH_LONG);
            }

            @Override
            public void onDownloadFinished(long totalBytes, String fileName, String appName) {
                if (!isValid()) {
                    return;
                }
                TToast.show(mContext, appName + " 下载成功,点击安装", Toast.LENGTH_LONG);

            }

            @SuppressWarnings("BooleanMethodIsAlwaysInverted")
            private boolean isValid() {
                return mTTAppDownloadListenerMap.get(adViewHolder) == this;
            }
        };
        //一个ViewHolder对应一个downloadListener, isValid判断当前ViewHolder绑定的listener是不是自己
        ad.setDownloadListener(downloadListener); // 注册下载监听器
        mTTAppDownloadListenerMap.put(adViewHolder, downloadListener);
    }

}

listitem_ad_native_express.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:ignore="HardcodedText">

    <FrameLayout
        android:id="@+id/iv_listitem_express"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>

item.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.2" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.8" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:text="TextView"
        android:textSize="30sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/guideline3"
        app:layout_constraintStart_toStartOf="@+id/guideline2"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值