android 自己定义视频播放器之2/1

非常久没更新博客,相信大家年后都比較忙。

今天给大家带来了一款视频播放器,首先确认的得有几点。

1、首先得有个播放视频的view。

2、加点额外功能进去左边上下滑动调节亮度,右边上下滑动调节声量;

3、视频当然得有快进和快退,左右滑动快进和快退;

4、可全屏播放;

5、临时仅仅做了离线播放。下篇博客再去研究在线播放。视频路径 这是视频本地路径,视频资源的话你们自己去找。目录会自己主动创建。放在该目录以下就能够了

private String Path = Environment.getExternalStorageDirectory() + “/wywVideo/

首先先贴上效果图:

咱们依据效果图一步一步的来。先进行布局:

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

    <com.wyw.activity.FullVideoView
        android:id="@+id/video_VideoView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ImageView
        android:id="@+id/video_img"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    <ImageView
        android:id="@+id/video_img_center_speed"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        />

    <RelativeLayout
        android:id="@+id/video_relative_right"
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_above="@+id/video_relative_buttom"
        android:layout_alignParentRight="true"
        android:background="@color/lightgray_50" >

        <ImageView
            android:id="@+id/video_imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:src="@drawable/right_video_img" />

        <ListView
            android:id="@+id/video_listview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/video_imageView"
            android:paddingRight="10dp" >
        </ListView>
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/video_relative_buttom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:background="@color/gray_50" >

        <ImageView
            android:id="@+id/video_img_last"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40dp"
            android:layout_centerVertical="true"
            android:src="@drawable/last_video_selector" />

        <ImageView
            android:id="@+id/video_img_start"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/video_img_last"
            android:src="@drawable/start_video_df" />

        <ImageView
            android:id="@+id/video_img_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/video_img_start"
            android:src="@drawable/next_video_selector" />

        <ImageView
            android:id="@+id/video_img_voice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@+id/video_img_full"
            android:src="@drawable/right_show_img" />

        <ImageView
            android:id="@+id/video_img_full"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="30dp"
            android:src="@drawable/big_video_selector" />

        <TextView
            android:id="@+id/video_txt_current_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_toRightOf="@+id/video_img_next"
            android:text="@string/play_time"
            android:textColor="@color/white" />

        <ImageView
            android:id="@+id/video_videoview_pres_bg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_toLeftOf="@+id/video_txt_max_time"
            android:layout_toRightOf="@+id/video_txt_current_time"
            android:background="@drawable/video_num_bg" />

        <ImageView
            android:id="@+id/video_videoview_pres_front"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_toRightOf="@+id/video_txt_current_time"
            android:background="@drawable/video_num_front" />

        <TextView
            android:id="@+id/video_txt_max_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:layout_toLeftOf="@+id/video_img_voice"
            android:text="@string/play_time"
            android:textColor="@color/white" />
    </RelativeLayout>

    <ImageView
        android:id="@+id/video_img_center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/video_brightness_bg"
        android:visibility="gone" />

    <FrameLayout
        android:id="@+id/video_frame"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/video_img_center"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="-30dp"
        android:visibility="gone" >

        <ImageView
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:background="@drawable/video_num_bg" />

        <ImageView
            android:id="@+id/video_img_pres_front"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="@drawable/video_num_front" />
    </FrameLayout>

</RelativeLayout>

该布局的图为

在这里咱们先把显示亮度和声音的布局隐藏掉。当须要的时候在显示出来。

如今则须要自己定义一个可全屏播放的自己定义VideoView出来代码例如以下:

package com.wyw.activity;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.VideoView;

public class FullVideoView extends VideoView {

    public FullVideoView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }
    public FullVideoView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }
    public FullVideoView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = getDefaultSize(0, widthMeasureSpec);
        int height = getDefaultSize(0, heightMeasureSpec);
        setMeasuredDimension(width, height);
    };
}

好,如今呢关键的部分来了。

首先呢得有滑动依据手势来区分和调节音量还是亮度或者是快进快退。

然后依据大小动态显示各自的进度条。然后呢在抬起手势中该隐藏的隐藏该初始化的初始化。播放时间呢我是用了一个延时线程,1000毫秒运行一次也就是1秒运行一次,正在播放长度大于视频总长度的话呢我就会吧当前线程给干掉。

这样就达到了时间1秒1跳的效果。我们还须要把视频长度转换成时间。

好了,说了这么多应该也几乎相同能明确大概意思了,该动真家伙了。

以下贴代码:

package com.wyw.activity;

import java.io.File;
import java.util.ArrayList;

import com.wyw.videodemo.R;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.ThumbnailUtils;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore.Video.Thumbnails;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;

/**
 * 视频播放界面
 *
 * @author WangYuWen
 * @version 1.0
 * @date 2015年3月5日
 */
public class MainActivity extends BaseActivity {

    /** 右边列表控件 */
    private ListView listview;
    /** 右边缩放控件 */
    private RelativeLayout right_relative;
    /** 上一首 */
    private ImageView img_last;
    /** 下一首 */
    private ImageView img_next;
    /** 播放 */
    private ImageView img_start;
    /** 全屏播放 */
    private ImageView img_full;
    /** 加减声音 */
    private ImageView img_voice;
    /** 列表适配器 */
    private VideoListAdapter adapter;
    /** 列表集合 */
    private ArrayList<VideoListBean> list;
    /** 播放视频的背景图片 */
    private ImageView video_img;

    /** 亮度或者声音的图片 */
    private ImageView img_center;
    /** 调节进度 */
    private ImageView img_pres_white;
    /** 底部视图栏 */
    private RelativeLayout buttom_relative;

    private View view;

    private FullVideoView video_VideoView;
    /** 当前播放时间 */
    private TextView txt_current_time;
    /** 总时间 */
    private TextView txt_max_time;
    /** 当前播放进度 */
    private ImageView img_white;
    /** 播放进度背景 */
    private ImageView img_bg;
    /** 拖放进度 */
    private ImageView img_center_speed;

    private AudioManager mAudioManager;
    /** 最大音量 */
    private int mMaxVolume;
    /** 当前声音 */
    private int mVolume = -1;
    /** 当前亮度 */
    private float mBrightness = -1f;
    /** 屏幕宽度 */
    private int width;
    /** 屏幕高度 */
    private int height;
    /** 手势 */
    private GestureDetector mGestureDetector;
    /** 视频总长度 */
    private long mVideo_total_length;
    /** 视频当前长度 */
    private long mVideo_current_length;
    /** 按下手势时的X点 */
    private float downX = 0;
    /** 按下手势时的Y点 */
    private float downY = 0;
    /** 移动手势时的Y点 */
    private float moveY = 0;
    /** 移动手势时的X点 */
    private float moveX = 0;
    /** 记录上一次移动手势时的X点 */
    private float OldMoveX = 0;
    /** 记录上一次移动手势时的y点 */
    private float OldMoveY = 0;
    /** 双数才运行(在用到的地方有具体的解释) */
    private int evens = 0;

    /** 是否显示全屏 */
    private boolean isVH = true;
    /** 是否快进了 */
    private boolean isVideo = false;
    /** 是否调节了音量 */
    private boolean isVoice = false;
    /** 是否调节了亮度 */
    private boolean isBright = false;
    /** 是否点击了開始播放 */
    private boolean isStart = false;
    /** 当前播放位置 */
    private int index_position = 0;

    private static final int handKey = 123;

    /** 视频路径 这是视频本地路径,资源的话你们自己去找,目录有创建,*/
    private String Path = Environment.getExternalStorageDirectory() + "/wywVideo/";

    @Override
    protected int getContentViewId() {
        return R.layout.activity_video_list;
    }

    @SuppressWarnings("deprecation")
    @Override
    protected void findViews() {
        img_last = (ImageView) findViewById(R.id.video_img_last);
        img_start = (ImageView) findViewById(R.id.video_img_start);
        img_next = (ImageView) findViewById(R.id.video_img_next);
        img_full = (ImageView) findViewById(R.id.video_img_full);
        img_voice = (ImageView) findViewById(R.id.video_img_voice);
        video_img = (ImageView) findViewById(R.id.video_img);

        img_center = (ImageView) findViewById(R.id.video_img_center);
        img_pres_white = (ImageView) findViewById(R.id.video_img_pres_front);

        txt_current_time = (TextView) findViewById(R.id.video_txt_current_time);
        txt_max_time = (TextView) findViewById(R.id.video_txt_max_time);
        img_white = (ImageView) findViewById(R.id.video_videoview_pres_front);
        img_bg = (ImageView) findViewById(R.id.video_videoview_pres_bg);
        img_center_speed = (ImageView) findViewById(R.id.video_img_center_speed);

        video_VideoView = (FullVideoView) findViewById(R.id.video_VideoView);

        view = findViewById(R.id.video_frame);
        // 获取屏幕宽度
        width = getWindowManager().getDefaultDisplay().getWidth();
        // 获取屏幕高度
        height = getWindowManager().getDefaultDisplay().getHeight();

        right_relative = (RelativeLayout) findViewById(R.id.video_relative_right);
        buttom_relative = (RelativeLayout) findViewById(R.id.video_relative_buttom);
        // 右边试图宽度为屏幕宽度的3分之1
        right_relative.getLayoutParams().width = width / 3;

        listview = (ListView) findViewById(R.id.video_listview);

        widgetListener();
    }

    @Override
    protected void init() {

        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

        File file = new File(Path);
        if (!file.exists()) {
            file.mkdirs();
        }

        list = new ArrayList<VideoListBean>();

        mGestureDetector = new GestureDetector(this, new MyGestureListener());

        adapter = new VideoListAdapter(MainActivity.this, list);
        listview.setAdapter(adapter);

        new Thread(runnable2).start();
    }

    /** 点击事件 */
    private void widgetListener() {
        /** 列表点击事件 */
        listview.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?

> parent, View view, int position, long id) {
                index_position = position;
                txt_max_time.setText(R.string.play_time);
                img_start.setImageResource(R.drawable.start_video_df);
                video_VideoView.stopPlayback();
                setVideo(position);
            }
        });

        /** 上一首 */
        img_last.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                index_position--;
                if (index_position>=0) {
                    txt_max_time.setText(R.string.play_time);
                    img_start.setImageResource(R.drawable.start_video_df);
                    video_VideoView.stopPlayback();
                    setVideo(index_position);
                }else{
                    index_position=0;
                }
            }
        });
        /** 下一首 */
        img_next.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                index_position++;
                img_start.setImageResource(R.drawable.start_video_df);
                txt_max_time.setText(R.string.play_time);
                video_VideoView.stopPlayback();
                setVideo(index_position);
            }
        });

        /** 播放 */
        img_start.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                video_img.setVisibility(View.GONE);
                if (video_VideoView.isPlaying()) {
                    video_VideoView.pause();
                    img_start.setImageResource(R.drawable.start_video_df);
                } else {
                    mVideo_total_length = video_VideoView.getDuration();// 获取视频总长度
                    // 设置总时长(总长度换算成时间)
                    txt_max_time.setText(length2time(mVideo_total_length));
                    isStart = true;
                    video_VideoView.start();
                    img_start.setImageResource(R.drawable.pause_video_df);
                    handler.postAtTime(runnable, 0);
                }
            }
        });

        /** 全屏 */
        img_full.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (isVH) {
                    WindowManager.LayoutParams params = getWindow().getAttributes();
                    params.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
                    getWindow().setAttributes(params);
                    getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

                    right_relative.setVisibility(View.GONE);
                    buttom_relative.setVisibility(View.GONE);

                    isVH = false;
                } else {
                    WindowManager.LayoutParams params = getWindow().getAttributes();
                    params.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
                    getWindow().setAttributes(params);
                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

                    buttom_relative.setVisibility(View.VISIBLE);
                    isVH = true;
                }
            }
        });
        /** 是否显示右边视图点击事件 */
        img_voice.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (right_relative.isShown()) {
                    right_relative.setVisibility(View.GONE);
                } else {
                    right_relative.setVisibility(View.VISIBLE);
                }
            }
        });
        /** 右边视图 */
        right_relative.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                right_relative.setVisibility(View.GONE);
            }
        });
    }

    private Runnable runnable2 = new Runnable() {

        @Override
        public void run() {
            doSearch(Path);
            Message message = handler.obtainMessage();
            message.what = handKey;
            handler.sendMessage(message);
        }
    };

    /**
     * 搜索该路径以下的全部文件
     *
     * @version 1.0
     * @createTime 2015年3月12日,下午2:11:47
     * @updateTime 2015年3月12日,下午2:11:47
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入改动内容,若无改动可不写.)
     *
     * @param path
     */
    private void doSearch(String path) {
        File file = new File(path);

        if (file.exists()) {
            if (file.isDirectory()) {
                File[] fileArray = file.listFiles();
                for (File f : fileArray) {
                    if (f.isDirectory()) {// 推断是否目录
                                // 目录为true
                        doSearch(f.getPath());
                    } else {
                        if (f.getName().endsWith("mp4") || f.getName().endsWith("3gp")) {
                            VideoListBean bean = new VideoListBean();
                            bean.setVideo_name(f.getName());
                            bean.setVideo_path(f.getAbsolutePath());
                            Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(f.getAbsolutePath(), Thumbnails.MINI_KIND);
                            if (bitmap != null) {
                                bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() * 300 / bitmap.getHeight(), 300, true);
                                bean.setVideo_imgbg(bitmap);
                            }
                            list.add(bean);
                        }
                    }
                }
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mGestureDetector.onTouchEvent(event))
            return true;

        // 处理手势结束
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_UP:
            endGesture();
            break;
        }
        return super.onTouchEvent(event);
    }

    /**
     * 手势结束
     *
     * @version 1.0
     * @createTime 2015年3月5日,上午11:36:43
     * @updateTime 2015年3月5日,上午11:36:43
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入改动内容,若无改动可不写.)
     *
     */
    private void endGesture() {
        if (!isVideo && !isVoice && !isBright) {
            if (right_relative.isShown()) {
                right_relative.setVisibility(View.GONE);
            }
            if (buttom_relative.isShown()) {
                buttom_relative.setVisibility(View.GONE);
            } else {
                buttom_relative.setVisibility(View.VISIBLE);
            }
        }

        isVideo = false;
        isVoice = false;
        isBright = false;

        OldMoveX = 0;
        OldMoveY = 0;

        // 隐藏
        img_center.setVisibility(View.GONE);
        img_center_speed.setVisibility(View.GONE);
        view.setVisibility(View.GONE);
    }

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            if (msg.what == handKey) {
                setVideo(index_position);
                adapter.notifyDataSetChanged();
            }
        };
    };

    /**
     * 设置Video该播放视频的准备和视频的背景图片
     *
     * @version 1.0
     * @createTime 2015年3月12日,下午2:17:55
     * @updateTime 2015年3月12日,下午2:17:55
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入改动内容,若无改动可不写.)
     *
     * @param position
     */
    @SuppressWarnings("deprecation")
    private void setVideo(int position) {
        if (list.size() > position && position>-1) {
            Drawable drawable = new BitmapDrawable(list.get(position).getVideo_imgbg());
            video_VideoView.setVideoPath(list.get(position).getVideo_path());
            video_VideoView.requestFocus();
            video_img.setVisibility(View.VISIBLE);
            video_img.setBackgroundDrawable(drawable);
        }
    }

    private Runnable runnable = new Runnable() {

        @Override
        public void run() {
            mVideo_current_length = video_VideoView.getCurrentPosition();

            if (mVideo_current_length >= mVideo_total_length) {
                mVideo_current_length = mVideo_total_length;
            }
            /** 设置当前时长 */
            txt_current_time.setText(length2time(mVideo_current_length));
            /** 设置视频进度 */
            LayoutParams layoutParams = (LayoutParams) img_white.getLayoutParams();
            layoutParams.width = (int) (((float) img_bg.getWidth()) / mVideo_total_length * mVideo_current_length);
            img_white.setLayoutParams(layoutParams);

            handler.postDelayed(runnable, 1000);

            if (mVideo_current_length >= mVideo_total_length) {
                handler.removeCallbacks(runnable);
            }

        }
    };

    /**
     * 调节音量
     *
     * @version 1.0
     * @createTime 2015年3月5日,上午11:16:35
     * @updateTime 2015年3月5日,上午11:16:35
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入改动内容,若无改动可不写.)
     *
     * @param num
     */
    private void setVoiceNum(float num) {
        evens++;//这里为什么要用个双数运行呢,由于手势滑动的太快音量仅仅有15,控制了下音量增减速度,不然略微滑动一下就到了最高或者最低这是我们用户不喜欢看到的。
        mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

        if (mVolume < 0) {
            mVolume = 0;
        }
        if (num < 0 && evens % 2 == 0) {
            mVolume -= 1;
        } else if (num > 0 && evens % 2 == 0) {
            mVolume += 1;
        }

        if (mVolume > mMaxVolume) {
            mVolume = mMaxVolume;
        } else if (mVolume < 0) {
            mVolume = 0;
        }

        img_center.setImageResource(R.drawable.video_voice_bg);
        img_center.setVisibility(View.VISIBLE);
        view.setVisibility(View.VISIBLE);

        // 变更声音
        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolume, 0);

        // 变更进度条
        ViewGroup.LayoutParams lp = img_pres_white.getLayoutParams();
        lp.width = DisplayUtils.dip2px(MainActivity.this, 100) * mVolume / mMaxVolume;
        img_pres_white.setLayoutParams(lp);
    }

    /**
     * 调节视频进度
     *
     * @version 1.0
     * @createTime 2015年3月5日,下午4:48:07
     * @updateTime 2015年3月5日,下午4:48:07
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入改动内容,若无改动可不写.)
     *
     * @param distanceX
     */
    private void onVideoSpeed(float distanceX) {
        mVideo_current_length = video_VideoView.getCurrentPosition();// 当前播放长度

        if (distanceX > 0) {// 往左滑动 --
            img_center_speed.setVisibility(View.VISIBLE);
            img_center_speed.setImageResource(R.drawable.retreat_video);
            mVideo_current_length -= 1000;// 快进之后长度
        } else if (distanceX < 0) {// 往右滑动 ++
            img_center_speed.setVisibility(View.VISIBLE);
            img_center_speed.setImageResource(R.drawable.speed_video);
            mVideo_current_length += 1000;// 快进之后长度
        }

        if (mVideo_current_length >= mVideo_total_length) {
            mVideo_current_length = mVideo_total_length;
        } else if (mVideo_current_length <= 0) {
            mVideo_current_length = 0;
        }
        video_VideoView.seekTo((int) mVideo_current_length);
        // //定位播放在哪个位置
        handler.postDelayed(runnable, 0);
    }

    /**
     * 将进度长度转变为进度时间
     *
     * @version 1.0
     * @createTime 2015年3月5日,下午4:25:05
     * @updateTime 2015年3月5日,下午4:25:05
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入改动内容,若无改动可不写.)
     *
     * @param length
     * @return
     */
    @SuppressLint("DefaultLocale")
    private String length2time(long length) {
        length /= 1000L;
        long minute = length / 60L;
        long hour = minute / 60L;
        long second = length % 60L;
        minute %= 60L;
        return String.format("%02d:%02d:%02d", hour, minute, second);
    }

    /**
     * 调节亮度
     *
     * @version 1.0
     * @createTime 2015年3月5日,上午11:16:44
     * @updateTime 2015年3月5日,上午11:16:44
     * @createAuthor WangYuWen
     * @updateAuthor WangYuWen
     * @updateInfo (此处输入改动内容,若无改动可不写.)
     *
     * @param percent
     */
    private void onBrightnessSlide(float percent) {
        WindowManager.LayoutParams lpa = getWindow().getAttributes();
        mBrightness = lpa.screenBrightness;

        img_center.setImageResource(R.drawable.video_brightness_bg);
        img_center.setVisibility(View.VISIBLE);
        view.setVisibility(View.VISIBLE);

        lpa.screenBrightness = mBrightness + percent;
        if (lpa.screenBrightness > 1.0f) {
            lpa.screenBrightness = 1.0f;
        } else if (lpa.screenBrightness < 0.01f) {
            lpa.screenBrightness = 0.01f;
        }
        getWindow().setAttributes(lpa);
        // 变更亮度进度条
        ViewGroup.LayoutParams lp = img_pres_white.getLayoutParams();
        lp.width = (int) (DisplayUtils.dip2px(MainActivity.this, 100) * lpa.screenBrightness);
        img_pres_white.setLayoutParams(lp);
    }

    private class MyGestureListener extends SimpleOnGestureListener {
        /** 双击 */
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            return true;
        }

        /** 滑动 */
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            // e1==按下的点 e2==移动的点
            downX = e1.getX();
            downY = e1.getY();
            moveX = e2.getX();
            moveY = e2.getY();
            if (OldMoveX == 0) {
                OldMoveX = downX;
                OldMoveY = downY;
            }
            if (Math.abs(moveY - downY) < Math.abs(moveX - downX) && !isVoice && !isBright && isStart) {
                handler.removeCallbacks(runnable);
                onVideoSpeed((OldMoveX - moveX) / width);
                OldMoveX = moveX;
                isVideo = true;
            } else {
                if (downX > width * 4 / 5 && !isVideo && !isBright) {// 右边滑动
                    setVoiceNum((OldMoveY - moveY) / height);
                    OldMoveY = moveY;
                    isVoice = true;
                } else if (downX < width / 5 && !isVideo && !isVoice) {// 左边滑动
                    onBrightnessSlide((OldMoveY - moveY) / height);
                    OldMoveY = moveY;
                    isBright = true;
                }
            }

            return super.onScroll(e1, e2, distanceX, distanceY);
        }
    }
}

方便一些朋友写。我这里也把适配器和数据集的代码也贴进来。

首先是数据(bean):

package com.wyw.activity;

import android.graphics.Bitmap;

public class VideoListBean{

    /** 视频id */
    private String Video_Id;
    /** 视频名字 */
    private String Video_name;
    /** 视频路径 */
    private String Video_path;
    /** 视频展示配置表-封面图URL */
    private Bitmap Video_imgbg;
    /** 创建时间 */
    private String Create_time;

    public Bitmap getVideo_imgbg() {
        return Video_imgbg;
    }

    public void setVideo_imgbg(Bitmap video_imgbg) {
        Video_imgbg = video_imgbg;
    }

    public String getCreate_time() {
        return Create_time;
    }

    public void setCreate_time(String create_time) {
        Create_time = create_time;
    }

    public String getVideo_Id() {
        return Video_Id;
    }

    public void setVideo_Id(String video_Id) {
        Video_Id = video_Id;
    }

    public String getVideo_name() {
        return Video_name;
    }

    public void setVideo_name(String video_name) {
        Video_name = video_name;
    }

    public String getVideo_path() {
        return Video_path;
    }

    public void setVideo_path(String video_path) {
        Video_path = video_path;
    }

}

适配器:

package com.wyw.activity;

import java.util.ArrayList;
import com.wyw.videodemo.R;

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class VideoListAdapter extends BaseAdapter {

    private Context context;

    private ArrayList<VideoListBean> list;

    public VideoListAdapter(Context context,ArrayList<VideoListBean> list){
        this.context=context;
        this.list=list;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @SuppressLint("InflateParams")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder viewHolder;
        final VideoListBean bean = list.get(position);
        if (convertView==null) {
            viewHolder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.item_video_listview, null);
            viewHolder.img_video = (ImageView) convertView.findViewById(R.id.item_video_img);
            viewHolder.txt_name = (TextView) convertView.findViewById(R.id.item_video_txt_name);
            viewHolder.txt_time = (TextView) convertView.findViewById(R.id.item_video_txt_time);
            convertView.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.txt_name.setText(bean.getVideo_name());
        viewHolder.img_video.setImageBitmap(bean.getVideo_imgbg());

        viewHolder.txt_time.setText(DateUtils.getDay());        

        return convertView;
    }

    private class ViewHolder{
        /**视频图片*/
        private ImageView img_video;
        /**视频名字*/
        private TextView txt_name;
        /**视频时间*/
        private TextView txt_time;
    }

}

隐藏各个控件我认为应该要有动画才好看。这个就交给你们延伸了。下次呢我会加上动画以及研究下在线播放解码之类的。

希望大家多多关注我的博客。多多支持我。

如有好意见或更好的方式欢迎留言谈论。

尊重原创转载请注明:(http://blog.csdn.net/u013895206) 侵权必究!

以下是地址传送门:

http://download.csdn.net/detail/u013895206/8494817

时间: 2024-09-29 09:50:07

android 自己定义视频播放器之2/1的相关文章

android 自定义视频播放器之2/1

很久没更新博客,相信大家年后都比较忙. 今天给大家带来了一款视频播放器,首先确认的得有几点. 1.首先得有个播放视频的view: 2.加点额外功能进去左边上下滑动调节亮度,右边上下滑动调节声量: 3.视频当然得有快进和快退,左右滑动快进和快退: 4.可全屏播放: 5.暂时只做了离线播放.下篇博客再去研究在线播放.视频路径 这是视频本地路径,视频资源的话你们自己去找,文件夹会自动创建,放在该文件夹下面就可以了 private String Path = Environment.getExterna

Android UI-自定义日历控件

Android UI-自定义日历控件 本篇博客笔者给大家分享一个日历控件,这里有个需求:要求显示当前月的日期,左右可以切换月份来查看日期. 我们想一想会如何去实现这样的一个控件,有开源的,但可能不太满足我们的特定的需求,这里笔者自定义了一个,读者可以根据自己的需求来修改代码.下面来说一下实现的思路: 首先我们要显示当前月份,自然我们要计算出当前的日期,并且把每一天对应到具体的星期,我们会有以下效果: 我们先想一下这样的效果用什么控件可以实现?很自然可以想到用网格视图GridView,但这里笔者使

ANDROID自己定义视图——onLayout源代码 流程 思路具体解释

简单介绍: 在自己定义view的时候.事实上非常easy.仅仅须要知道3步骤: 1.測量--onMeasure():决定View的大小 2.布局--onLayout():决定View在ViewGroup中的位置 3.绘制--onDraw():怎样绘制这个View. 而第3步的onDraw系统已经封装的非常好了,基本不用我们来担心,仅仅须要专注到1,2两个步骤就中好了. 第一步的測量,能够參考我之前的文章:(ANDROID自己定义视图--onMeasure流程.MeasureSpec具体解释) 而

Android自己定义控件皮肤

Android自己定义控件皮肤 对于Android的自带控件,其外观仅仅能说中规中矩,而我们平时所示Android应用中,一个简单的button都做得十分美观.甚至于很多button在按下时的外观都有一定变化,用户体验十分好. 这当中,就涉及到了Android自己定义控件属性的操作方法,下面操作以实现自己定义button皮肤为例. 1. 我们要自己定义将要实现的外观状态.能够是图片或者是自己定义的xml,这是我们直接自己定义不同状态的颜色xml,在values文件夹下新建colors.xml,代

android 自己定义控件属性(TypedArray以及attrs解释)

近期在捣鼓android 自己定义控件属性,学到了TypedArray以及attrs.在这当中看了一篇大神博客Android 深入理解Android中的自己定义属性.我就更加深入学习力一番.我就沿着这个学习,讲一下流程吧,兴许一篇还有应用. 1.attrs文件编写 <?xml version="1.0" encoding="utf-8"?> <resources> <attr name="titleText" for

46.Android 自己定义Dialog

46.Android 自己定义Dialog Android 自己定义Dialog 前言 提示Dialog 提示Dialog 效果图 菜单Dialog 菜单Dialog 效果图 DialogActivity 前言 提供两套自己定义Dialog模板 第一种.提示Dialog,有消失时间. 另外一种,菜单Dialog,用于用户交互. 提示Dialog CustomDialog public class CustomDialog extends Dialog { private TextView dia

Android自己定义组件系列【6】——进阶实践(3)

上一篇<Android自己定义组件系列[5]--进阶实践(2)>继续对任老师的<可下拉的PinnedHeaderExpandableListView的实现>进行了分析,这一篇计划中间插一段"知识点",对Android中的事件分发机制进行解析.细心的朋友可能会发现,打开大牛写的Android项目,里面非常多组件都是自己定义的(这就是为什么界面和体验这么吸引你的原因),可是要灵活的去自己定义组件就必须对手势(也就是各种监听)必须熟悉,能处理好事件之间的关系. 先看一

Android 自己定义ViewGroup 实战篇 -&amp;gt; 实现FlowLayout

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38352503 .本文出自[张鸿洋的博客] 1.概述 上一篇已经基本给大家介绍了怎样自己定义ViewGroup.假设你还不了解,请查看:Android 手把手教您自定ViewGroup ,本篇将使用上篇介绍的方法,给大家带来一个实例:实现FlowLayout,何为FlowLayout,假设对Java的Swing比較熟悉的话一定不会陌生.就是控件依据ViewGroup的宽,自己主动

Android 自己定义控件实现刮刮卡效果 真的就仅仅是刮刮卡么

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40162163 , 本文出自:[张鸿洋的博客] 非常久以前也过一个html5的刮刮卡效果~~上次看到有人写Android的刮刮卡效果~~于是乎产生了本篇博客~~此类样例也比較多了,大家能够百度看看~只是还是通过本样例,带大家发掘一下.里面隐含的知识~ 1.Xfermode以及PorterDuff 假设大家还记得,以前在博客:完美实现图片圆角和圆形 简介过圆角的实现原理也是基于这个