2. Música en la nube NetEase de alta imitación de Android: interfaz de guía e implementación de la interfaz de publicidad

representaciones

guía_de_anuncio_de_arte.png

Las representaciones son anuncios de imágenes, anuncios de video e interfaces de guía en secuencia.

Serie Artículo Directorio Navegación

Tabla de contenido

1. Análisis de implementación

La interfaz de publicidad es para mostrar imágenes y videos, por lo que puede colocar un control de imagen, un control de video, un botón de salto, un botón de aviso y un aviso de precarga de WiFi en el contenedor superior.

2. Diseño de la interfaz de publicidad

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context=".component.ad.activity.AdActivity">
    <!--图片广告-->
    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop" />

    <!--视频播放器
    VideoView默认没法设置视频填充整个控件,所以不用他-->
    <com.tencent.rtmp.ui.TXCloudVideoView
        android:id="@+id/video"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone" />
    <!--/播放器-->

    <!--广告控制层-->
    <RelativeLayout
        android:id="@+id/ad_control"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/preload"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/padding_meddle"
            android:layout_marginTop="@dimen/d50"
            android:layout_marginBottom="@dimen/d50"
            android:background="@drawable/shape_button_transparent_radius_small"
            android:gravity="center"
            android:padding="@dimen/d5"
            android:text="@string/wifi_preload"
            android:textColor="?attr/colorLightWhite"
            android:textSize="@dimen/text_small"
            android:visibility="gone" />

        <!--跳过广告按钮-->
        <TextView
            android:id="@+id/skip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginTop="@dimen/d50"
            android:layout_marginRight="@dimen/padding_large"
            android:layout_marginBottom="@dimen/d50"
            android:background="@drawable/shape_button_transparent_radius_small"
            android:gravity="center"
            android:padding="@dimen/padding_meddle"
            android:textColor="?attr/colorLightWhite"
            android:textSize="@dimen/text_meddle"
            app:cornerRadius="@dimen/d30"
            tools:text="@string/skip_ad_count" />
            <!--打开广告按钮-->
            <TextView
                android:id="@+id/primary"
                android:layout_width="match_parent"
                android:layout_height="@dimen/d60"
                android:background="@drawable/shape_button_transparent_radius_large"
                android:gravity="center"
                android:text="@string/ad_click_tip"
                android:textColor="?attr/colorLightWhite"
                android:textSize="@dimen/text_large"
                app:cornerRadius="@dimen/d30" />
        </com.facebook.shimmer.ShimmerFrameLayout>
    </RelativeLayout>
</RelativeLayout>

3. Anuncios gráficos

Los datos publicitarios se almacenan en caché localmente en la página de inicio por adelantado, y el propósito es mostrarlos localmente más rápido, porque la interfaz publicitaria es de solo unos segundos y es una pérdida de tiempo ir a la red para solicitar datos.

@Override
protected void initDatum() {
    super.initDatum();

    //获取广告信息
    data = sp.getSplashAd();
    if (data == null) {
        next();
        return;
    }

    //显示广告信息
    show();
}

private void show() {
    File targetFile = FileUtil.adFile(getHostActivity(), data.getIcon());
    if (!targetFile.exists()) {
        //记录日志,因为正常来说,只要保存了,文件不能丢失
        next();
        return;
    }

    SuperViewUtil.show(binding.adControl);

    switch (data.getStyle()) {
        case Constant.VALUE0:
            showImageAd(targetFile);
            break;
        case Constant.VALUE10:
            showVideoAd(targetFile);
            break;
    }
}

/**
 * 显示视频广告
 *
 * @param data
 */
private void showVideoAd(File data) {
    SuperViewUtil.show(binding.video);
    SuperViewUtil.show(binding.preload);

    //在要用到的时候在初始化,更节省资源,当然播放器控件也可以在这里动态创建
    //设置播放监听器

    //创建 player 对象
    player = new TXVodPlayer(getHostActivity());

    //静音,当然也可以在界面上添加静音切换按钮
    player.setMute(true);

    //关键 player 对象与界面 view
    player.setPlayerView(binding.video);

    //设置播放监听器
    player.setVodListener(this);

    //铺满
    binding.video.setRenderMode(TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN);

    //开启硬件加速
    player.enableHardwareDecode(true);

    player.startPlay(data.getAbsolutePath());
}

/**
 * 显示图片广告
 *
 * @param data
 */
private void showImageAd(File data) {
    ImageUtil.showLocalImage(getHostActivity(), binding.image, data.getAbsolutePath());

    startCountDown(5000);
}

saltar anuncios

Saltarse un anuncio es cancelar la cuenta atrás e ir directamente a la siguiente interfaz.

//跳过广告按钮
binding.skip.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //取消倒计时
        cancelCountDown();

        next();
    }
});

haga clic en el anuncio

Al hacer clic en el anuncio, se cancela la cuenta regresiva, se ingresa a la interfaz principal y luego se muestra la interfaz de publicidad.

Diseño de interfaz de arranque

//点击广告按钮
binding.primary.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //取消倒计时
        cancelCountDown();

        action = Constant.ACTION_AD;

        next();
    }
});

Lógica de la interfaz de arranque

Desplace el contenedor ViewPager hacia la izquierda y hacia la derecha en la parte superior, también puede usar ViewPager2, el medio es el indicador y la parte inferior es el botón.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ixuea="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--左右滚动控件-->
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    ...

    <!--按钮容器-->
    <LinearLayout
        android:layout_marginBottom="@dimen/d30"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <!--占位控件-->
        <View
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="1" />

        <!--登录注册按钮-->
        <com.google.android.material.button.MaterialButton
            android:id="@+id/login_or_register"
            style="@style/SuperButton.Primary"
            android:layout_width="wrap_content"
            android:minWidth="@dimen/d130"
            android:text="@string/login_or_register" />

        <include layout="@layout/fill" />

        <!--立即体验按钮-->
        <com.google.android.material.button.MaterialButton
            android:id="@+id/experience_now"
            style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
            android:layout_width="wrap_content"
            android:layout_height="@dimen/d55"
            android:layout_centerVertical="true"
            android:layout_marginHorizontal="@dimen/d5"
            android:layout_toRightOf="@+id/select_image"
            android:backgroundTint="?attr/colorLightWhite"
            android:minWidth="@dimen/button_width_large"
            android:text="@string/experience_now"
            android:textColor="@color/black80"
            android:textSize="@dimen/text_small"
            ixuea:strokeColor="?attr/colorPrimary"
            ixuea:strokeWidth="@dimen/d1" />

        <include layout="@layout/fill" />
    </LinearLayout>
</LinearLayout>

Descargar anuncios

Ya sea una imagen o un video, está en el modo de archivo. Por supuesto, antes de descargar, es necesario juzgar si es WiFi y descargarlo si no está descargado.

private void downloadAd(Ad data) {
    if (SuperNetworkUtil.isWifiConnected(getHostActivity())) {
        sp.setSplashAd(data);

        //判断文件是否存在,如果存在就不下载
        File targetFile = FileUtil.adFile(getHostActivity(), data.getIcon());
        if (targetFile.exists()) {
            return;
        }

        new Thread(
                new Runnable() {
                    @Override
                    public void run() {

                        try {
                            //FutureTarget会阻塞
                            //所以需要在子线程调用
                            FutureTarget<File> target = Glide.with(getHostActivity().getApplicationContext())
                                    .asFile()
                                    .load(ResourceUtil.resourceUri(data.getIcon()))
                                    .submit();

                            //获取下载的文件
                            File file = target.get();

                            //将文件拷贝到我们需要的位置
                            FileUtils.moveFile(file, targetFile);

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
        ).start();
    }
}

Resumir

No importa qué interfaz sea, no es difícil, pero como dijimos, escribir código es como el arte, y es bastante problemático escribir los detalles, como: si descargar anuncios debe descargarse cuando la red está inactiva, entonces como para evitar afectar las solicitudes normales de la red, al mismo tiempo, después de la descarga, es necesario agregar un cierto mecanismo para evitar el salto fácil de anuncios, etc.; si desea generar ingresos, las grandes empresas tienen sus propias plataformas de publicidad, y es más conveniente para proyectos pequeños y medianos usar el SDK de agregación.

Supongo que te gusta

Origin juejin.im/post/7121989624376868877
Recomendado
Clasificación