基于移动互联网的短视频APP设计

本文详细介绍了开发一款简易短视频APP的过程,包括网络数据获取、列表组件使用、视频播放与录制、手势检测等功能实现。核心技术涉及Retrofit、JSON解析、 Glide图片加载,以及自定义控件与属性动画。此外,还探讨了视频上传和弹幕等潜在扩展功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

  1. 相关技术 3
    1.1 网络retrofit与json 3
    1.2列表组件及复用机制 3
    1.3 glide加载图片 3
    1.4 Activity的生命周期与onSaveInstanceState 4
    1.5自定义控件与属性动画 4
    1.6手势检测GestureDetector 4
  2. 系统功能需求 5
    2.1功能描述 5
    2.1.1视频信息流列表显示(包含封面图) 5
    2.1.2视频播放 5
    2.1.3视频拍摄录制 5
    2.2需求分析 6
  3. 系统设计与实现 6
    3.1总体设计与系统组成 6
    3.2模块设计与关键代码的解释 7
    3.2.1网络数据获取模块 7
    3.2.2循环列表模块 8
    3.2.3录制视频模块 9
    3.2.4视频展示模块 10
    3.2.5手势识别模块 10
    3.2.6爱心特效模块 11
  4. 系统可能的扩展 12
    4.1视频上传 12
    4.2 视频弹幕 12
  5. 总结体会 12
    2.2需求分析
    本系统由两个页面(Activity)构成,其中一个界面用列表展示视频信息流,包括每个视频的封面、作者昵称、描述、作者头像等相关信息。该页面还应包含一个拍摄按钮。当用户点击视频封面时,可以跳转到播放界面播放相应视频。当用户点击拍摄按钮时,APP调起系统相机录制视频,完成后返回APP,然后跳转到播放界面播放自己拍摄的视频。
    另一个界面用来播放视频,当用户单击屏幕时可以控制视频的播放与暂停,当用户双击视频时,则会出现点赞爱心的动画效果。
    本系统是一个简易的短视频APP,主体为视频信息流模块与视频播放模块这两大模块,在此基础上实现其它更加有趣的功能,例如在视频播放模块中实现双击视频窗口弹出点赞爱心图标的功能等等。
    视频信息流列表又包含网络数据获取模块、循环列表模块、录制视频模块。其中网络数据获取模块用来从网络API中获取相应的视频信息,再传给循环列表模块。循环列表模块用来展示视频信息流,本文转载自http://www.biyezuopin.vip/onews.asp?id=15118包括视频的封面图与相应的视频信息(比如视频的作者、头像等等),并且点击相应视频封面跳转到视频播放模块自动开始播放相应视频。录制视频模块用来调起系统相机录制视频,拍摄完成后跳转到视频播放模块开始播放所拍视频,拍摄失败提示“视频录制失败”。
    视频播放模块包含了视频展示模块、手势识别模块、爱心特效模块。其中视频展示模块实现视频播放功能,并将触屏事件传给手势识别模块。手势识别模块实现单击与双击事件的识别,单击控制视频的播放与暂停,双击产生点赞爱心图标。爱心特效模块实现了爱心出现、旋转、向上飞、表大变透明、最后消失的动画效果。
package com.example.finalwork;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends AppCompatActivity implements MyAdapter.MyItemClickListener {
    private List<Video> videos;
    private ViewPager2 viewPager2;
    private MyAdapter.MyItemClickListener listener;
    private Context context;
    private int position;
    private TextView capture;
    private static final int REQUEST_CODE = 233;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager2=findViewById(R.id.videoList);
        capture=findViewById(R.id.nav3);
        listener=this;
        context=this;
        if(savedInstanceState!=null){
            position=savedInstanceState.getInt("position");
        }else{
            position=0;
        }
        capture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MediaStore.ACTION_VIDEO_CAPTURE);//调起系统相机
                startActivityForResult(intent,REQUEST_CODE);//等待返回结果
            }
        });

        Retrofit retrofit=new Retrofit.Builder()//实例化Retrofit
                .baseUrl("https://beiyou.bytedance.com/")
                .addConverterFactory(GsonConverterFactory.create())//设置Gson的数据解析器
                .build();
        ApiService apiService=retrofit.create(ApiService.class);//通过Retrofit实例创建接口服务对象
        //接口服务对象调用接口中的方法,获取Call对象,接着Call对象执行请求
        apiService.getVideos().enqueue(new Callback<Video[]>() {
            @Override
            public void onResponse(Call<Video[]> call, Response<Video[]> response) {
                if(response.body()!=null){
                    //获取数据成功时将Video数组转成Video列表,方便处理
                    videos = new ArrayList<Video>(Arrays.asList(response.body()));
                    //将Video列表传给viewpage2
                    viewPager2.setAdapter(new MyAdapter(videos,listener,context));
                    //设置viewpage2的item为之前的item
                    viewPager2.setCurrentItem(position,false);
                }else{
                    Toast.makeText(MainActivity.this,"数据为空",Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<Video[]> call, Throwable t) {
                Toast.makeText(MainActivity.this,t.getMessage(),Toast.LENGTH_SHORT).show();
            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==REQUEST_CODE&&resultCode==RESULT_OK){
            //视频录制成功后跳转到播放界面进行播放
            Uri uri=data.getData();
            Intent intent=new Intent(this,VideoPlayer.class);
            intent.putExtra("url",uri.toString());
            startActivity(intent);
        }else{
            Toast.makeText(MainActivity.this,"视频录制失败",Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onItemClick(String url,int pos) {
        position=pos;
        Intent intent=new Intent(this,VideoPlayer.class);
        intent.putExtra("url",url);
        startActivity(intent);
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("position",position);
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shejizuopin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值