手机影音01

阅读原文

01-splash页面

public class SplashActivity extends AppCompatActivity
{
    private static final String TAG = SplashActivity.class.getSimpleName();//"SplashActivity"
    private boolean isStartMain = false;//是否进入主界面标志
    private Handler handler = new Handler();

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

        handler.postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                //两秒后才执行到这里
                //执行在主线程中
                startMainActivity();
                Log.e(TAG, "当前线程名称==" + Thread.currentThread().getName());
            }
        }, 2000);
    }



    /**
     * 跳转到主页面,并且把当前页面关闭掉
     */
    private void startMainActivity()
    {
        if (!isStartMain)
        {
            isStartMain = true;
            Intent intent = new Intent(this, MainActivity.class);
            startActivity(intent);
            //关闭当前页面
            finish();
        }

    }

      /**
       * 有一个bug,启动了多次Activity,如何解决?
       * 1.设置为启动的Activity只能是单例。
       *   在功能清单文件android:launchMode="singleTask"
       * 2.从源头上控制,执行代码只一次
       */
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        Log.e(TAG, "onTouchEvent==Action" + event.getAction());
        startMainActivity();
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDestroy()
    {
        //把所有的消息和回调移除
        handler.removeCallbacksAndMessages(null);
        super.onDestroy();
    }
}

02-MainActivity主页面布局

2.1activity_main.xml




    
    

    

    

    

    


        


        


        


        


    



2.2样式中引用如下



2.3RadioButton文字颜色

rb_bottom_textcolor_selector.xml



    
    


03-基类BasePager

public abstract class BasePager
{

    /**
     * 上下文
     */
    public final Context context;
    /**
     * 接收各个页面的实例
     */
    public View rootView;
    public boolean isInitData;

    public BasePager(Context context)
    {
        this.context = context;
        rootView = initView();
    }

    /**
     * 强制子页面实现该方法,实现想要的特定的效果
     *
     * @return
     */
    public abstract View initView();


    /**
     * 当子页面,需要绑定数据,或者联网请求数据并且绑定的时候,重写该方法
     */
    public void initData()
    {

    }
}

04-监听RadioGroup的状态

4.1 在MainActivity的onCreate方法中初始化各个页面

        private RadioGroup rg_bottom_tag;
        private Fragment fragment;
        /**
         * 页面的集合
         */
        private ArrayList basePagers;
    
        /**
         * 选中的位置
         */
        private int position;

        /**
         * 初始化各个页面
         */
        pbasePagers = new ArrayList<>();
        basePagers.add(new VideoPager(this));//添加本地视频页面-0
        basePagers.add(new AudioPager(this));//添加本地音乐页面-1
        basePagers.add(new NetVideoPager(this));//添加网络视频页面-2
        basePagers.add(new NetAudioPager(this));//添加网络音频页面-3


        //设置RadioGroup的监听
        rg_bottom_tag.setOnCheckedChangeListener(new MyOnCheckedChangeListener());
        rg_bottom_tag.check(R.id.rb_video);//默认选中首页

4.2 MyOnCheckedChangeListener

class MyOnCheckedChangeListener implements RadioGroup.OnCheckedChangeListener
    {

        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId)
        {

            switch (checkedId)
            {
                default:
                    position = 0;
                    break;
                case R.id.rb_audio://音频
                    position = 1;
                    break;
                case R.id.rb_net_video://网络视频
                    position = 2;
                    break;
                case R.id.rb_netaudio://网络音频
                    position = 3;
                    break;
            }

            setFragment();
        }
    }

4.3设置不同页面

    /**
     * 把页面添加到Fragment中
     */
    private void setFragment()
    {
        //1.得到FragmentManger
        FragmentManager manager = getSupportFragmentManager();
        //2.开启事务
        FragmentTransaction ft = manager.beginTransaction();
        //3.替换
        ft.replace(R.id.fl_main_content, new Fragment()
        {
            @Nullable
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
            {
                BasePager basePager = getBasePager();
                if (basePager != null)
                {
                    //各个页面的视图
                    return basePager.rootView;
                }
                return null;
            }
        });
        //4.提交事务
        ft.commit();

    }

    /**
     * 根据位置得到对应的页面
     *
     * @return
     */
    private BasePager getBasePager()
    {
        BasePager basePager = basePagers.get(position);
        if (basePager != null && !basePager.isInitData)
        {
            basePager.initData();//联网请求或者绑定数据
            basePager.isInitData = true;
        }
        return basePager;
    }

05-屏蔽各个页面重复初始化数据

5.1在主页面中屏蔽

if (basePager != null && !basePager.isInitData)
        {
            basePager.initData();//联网请求或者绑定数据
            basePager.isInitData = true;
        }

06-本地视频列表VideoPager

6.1 顶部标题栏布局





    


    

    


        

        

    


    


6.2 自定义的顶部标题栏点击事件

public class TitleBar extends LinearLayout implements View.OnClickListener
{

    private View tv_search;

    private View rl_game;

    private View iv_record;
    private Context context;

    /**
     * 在代码中实例化该类的时候使用这个方法
     *
     * @param context
     */
    public TitleBar(Context context)
    {
        this(context, null);
    }

    /**
     * 当在布局文件使用该类的时候,Android系统通过这个构造方法实例化该类
     *
     * @param context
     * @param attrs
     */
    public TitleBar(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);

    }

    /**
     * 当需要设置样式的时候,可以使用该方法
     *
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public TitleBar(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        this.context = context;
    }

    /**
     * 当布局文件加载完成的时候回调这个方法
     */
    @Override
    protected void onFinishInflate()
    {
        super.onFinishInflate();
        //得到孩子的实例
        tv_search = getChildAt(1);
        rl_game = getChildAt(2);
        iv_record = getChildAt(3);

        //设置点击事件
        tv_search.setOnClickListener(this);
        rl_game.setOnClickListener(this);
        iv_record.setOnClickListener(this);

    }

    @Override
    public void onClick(View v)
    {
        switch (v.getId())
        {
            case R.id.tv_search://搜索
                Toast.makeText(context, "搜索", Toast.LENGTH_SHORT).show();
                break;
            case R.id.rl_game://游戏
                Toast.makeText(context, "游戏", Toast.LENGTH_SHORT).show();
                break;
            case R.id.iv_record://播放历史
                Toast.makeText(context, "播放历史", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

6.3 视频列表显示

6.3.1 视频列表的布局文件




    

    

    




6.3.2 得到手机里面的视频和屏幕3MB以下视频

    /**
     * 从本地的sdcard得到数据
     * //1.遍历sdcard,后缀名
     * //2.从内容提供者里面获取视频
     * //3.如果是6.0的系统,动态获取读取sdcard的权限
     */
    private void getDataFromLocal()
    {
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                //SystemClock.sleep(2000);延迟2s加载
                isGrantExternalRW((Activity) context);
                mediaItems = new ArrayList();
                ContentResolver contentResolver = context.getContentResolver();
                Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                String[] objs =
                        {
                                MediaStore.Video.Media.DISPLAY_NAME,//视频文件在sdcard的名称
                                MediaStore.Video.Media.DURATION,//视频总时长
                                MediaStore.Video.Media.SIZE,//视频的文件大小
                                MediaStore.Video.Media.DATA,//视频的绝对地址
                                MediaStore.Video.Media.ARTIST,//歌曲的演唱者
                        };
                Cursor cursor = contentResolver.query(uri, objs, null, null, null);
                if (cursor != null)
                {
                    while (cursor.moveToNext())
                    {
                        MediaItem mediaItem = new MediaItem();

                        mediaItems.add(mediaItem);//写在上面

                        String name = cursor.getString(0);//视频的名称
                        mediaItem.setName(name);

                        long duration = cursor.getLong(1);//视频的时长
                        mediaItem.setDuration(duration);

                        long size = cursor.getLong(2);//视频的文件大小
                        mediaItem.setSize(size);

                        String data = cursor.getString(3);//视频的播放地址
                        mediaItem.setData(data);

                        String artist = cursor.getString(4);//艺术家
                        mediaItem.setArtist(artist);
                    }
                    cursor.close();//释放
                }
                //Handler发消息
                handler.sendEmptyMessage(10);
            }
        }).start();
    }

6.3.3 视频显示出来

private Handler handler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            super.handleMessage(msg);
            if (mediaItems != null && mediaItems.size() > 0)
            {
                //有数据
                //设置适配器
                videoPagerAdapter = new VideoPagerAdapter(context, mediaItems,false);
                listview.setAdapter(videoPagerAdapter);
                //把文本隐藏
                tvNomedia.setVisibility(View.GONE);
            }
            else
            {
                //没有数据
                //文本显示
                tvNomedia.setVisibility(View.VISIBLE);
            }


            //ProgressBar隐藏
            pbLoading.setVisibility(View.GONE);
        }
    };

6.3.4 适配器

/**
 * VideoPager的适配器
 */
public class VideoPagerAdapter extends BaseAdapter
{
    private Context context;
    private final boolean isVideo;
    private final ArrayList mediaItems;
    private Utils utils;

    public VideoPagerAdapter(Context context, ArrayList mediaItems,boolean isVideo)
    {
        this.context = context;
        this.mediaItems = mediaItems;
        this.isVideo = isVideo;
        utils = new Utils();
    }

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

    @Override
    public Object getItem(int position)
    {
        return null;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        ViewHolder viewHolder;
        if (convertView == null)
        {
            convertView = View.inflate(context, R.layout.item_video_pager, null);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        }
        else
        {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        //根据position得到列表中对应位置的数据
        MediaItem mediaItem = mediaItems.get(position);
        viewHolder.tvName.setText(mediaItem.getName());
        viewHolder.tvSize.setText(Formatter.formatFileSize(context, mediaItem.getSize()));
        viewHolder.tvTime.setText(utils.stringForTime((int) mediaItem.getDuration()));

        return convertView;
    }

    static class ViewHolder
    {
        @Bind(R.id.iv_icon)
        ImageView ivIcon;
        @Bind(R.id.tv_name)
        TextView tvName;
        @Bind(R.id.tv_time)
        TextView tvTime;
        @Bind(R.id.tv_size)
        TextView tvSize;

        ViewHolder(View view)
        {
            ButterKnife.bind(this, view);
        }
    }
}

6.4 视频列表的Item完成和相关数据处理

6.4.1 item_video_pager.xml




    

    

        

        
    

    

    



07-播放器的控制面板

7.1 播放器控制栏顶部




    

        

            

            

            
        


        

            

7.2 系统播放器布局




    

    

    

    



08-视频seekBar进度更新

8.1 设置总时间和seeKBar的总长度,在准备好了的回调中设置

int duration = videoview.getDuration();
//把毫秒转换成 12:22.40
tv_duration.setText(utils.stringForTime(duration));
          
//设置视频的总长度为video_seekBar的多少等分
video_seekBar.setMax(duration);
          
//发消息开始更新
handler.sendEmptyMessage(PROGRESS);

09-实现视频的拖动

class VideoOnSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener
    {

        /**
         * 当手指滑动的时候,会引起SeekBar进度变化,会回调这个方法
         *
         * @param seekBar
         * @param progress
         * @param fromUser 如果是用户引起的true,不是用户引起的false
         */
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
        {
            if (fromUser)
            {
                videoview.seekTo(progress);
            }

        }

        /**
         * 当手指触碰的时候回调这个方法
         *
         * @param seekBar
         */
        @Override
        public void onStartTrackingTouch(SeekBar seekBar)
        {

            handler.removeMessages(HIDE_MEDIACONTROLLER);
        }

        /**
         * 当手指离开的时候回调这个方法
         *
         * @param seekBar
         */
        @Override
        public void onStopTrackingTouch(SeekBar seekBar)
        {
            handler.sendEmptyMessageDelayed(HIDE_MEDIACONTROLLER, 4000);
        }
    }


 //设置SeeKbar状态变化的监听
        seekbarVideo.setOnSeekBarChangeListener(new VideoOnSeekBarChangeListener());

010-设置电池状态

10.1 监听电量变化广播

    utils = new Utils();
    //注册电量广播
    receiver = new MyReceiver();
    IntentFilter intentFiler = new IntentFilter();
    //当电量变化的时候发这个广播
    intentFiler.addAction(Intent.ACTION_BATTERY_CHANGED);
    registerReceiver(receiver, intentFiler);




 class MyReceiver extends BroadcastReceiver
    {

        @Override
        public void onReceive(Context context, Intent intent)
        {
            int level = intent.getIntExtra("level", 0);//0~100;
            setBattery(level);
        }
    }

10.2电量刷新方法

  /**
   * 设置电量的状态
   */
  private void setBattery(int level)
    {
        if (level <= 0)
        {
            ivBattery.setImageResource(R.drawable.ic_battery_0);
        }
        else if (level <= 10)
        {
            ivBattery.setImageResource(R.drawable.ic_battery_10);
        }
        else if (level <= 20)
        {
            ivBattery.setImageResource(R.drawable.ic_battery_20);
        }
        else if (level <= 40)
        {
            ivBattery.setImageResource(R.drawable.ic_battery_40);
        }
        else if (level <= 60)
        {
            ivBattery.setImageResource(R.drawable.ic_battery_60);
        }
        else if (level <= 80)
        {
            ivBattery.setImageResource(R.drawable.ic_battery_80);
        }
        else if (level <= 100)
        {
            ivBattery.setImageResource(R.drawable.ic_battery_100);
        }
        else
        {
            ivBattery.setImageResource(R.drawable.ic_battery_100);
        }
    }

11-得到系统时间并且更新显示

11.1得到系统时间

        /**
         * 得到系统时间
         *
         * @return
         */
        private String getSysteTime()
        {
            SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
            return format.format(new Date());
        }

11.2在hanlder设置更新

//设置系统时间
tv_system_time.setText(utils.getSystemTime());

你可能感兴趣的:(手机影音01)