音乐播放器-MainFragment分析5

来源:互联网 发布:linux tar解压缩 zip 编辑:程序博客网 时间:2024/05/01 10:15

UIManager在MainFragment里面一共使用了3次,除了构造函数,一次是

mUIManager.setOnRefreshListener(this);//Mainfragment里面实现了OnRefreshListener接口,该接口的定义却是在UIManager里面

一次是:

mUIManager.setContentType(from);

构造函数里面的内容很容易理解,就是

  initBroadCast();收到背景更改的广播后更改sharepreference所设置的背景文件名,并给布局更换背景。
  initBg();更改背景
  init();初始化为个viewpager和2个view容器


在setOnRefreshListener()方法里面的this也就是MainFragment复写了onRefresh()方法,

@Overridepublic void onRefresh() {refreshNum();}

在refreshNum()里面更新(或初始化)了GridView里面的音乐数量,我的最爱数量,文件夹数量等:

public void refreshNum() {int musicCount = mMusicDao.getDataCount();int artistCount = mArtistDao.getDataCount();int albumCount = mAlbumDao.getDataCount();int folderCount = mFolderDao.getDataCount();int favoriteCount = mFavoriteDao.getDataCount();mAdapter.setNum(musicCount, artistCount, albumCount, folderCount,favoriteCount);}


该类里面占据很大一部分的就是setContentType(),通过switch分支设置ViewPager。

先看看ViewPager的几个关键方法:

setCurrentItem()设置显示 的是哪一页

setAdapter()这就需要给ViewPager自定义Adapter了

自定义Adapter有许多种方法,此处采用的是继承PageAdapter

很简单,作为一个容器,关键的就是要有有基本构造,添加删除方法就行了。

private class MyPagerAdapter extends PagerAdapter {private List<View> listViews;public MyPagerAdapter(List<View> views) {this.listViews = views;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {container.removeView(listViews.get(position));// 删除页卡}@Overridepublic Object instantiateItem(ViewGroup container, int position) {// 这个方法用来实例化页卡container.addView(listViews.get(position));// 添加页卡return listViews.get(position);}@Overridepublic int getCount() {return listViews.size();// 返回页卡的数量}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;// 官方提示这样写}}

下面开始正题,该类是个工具类,通过该类可以控制动态生成View并通过ViewPager来显示,其最重要的方法是setContentType,我们再回到MainFragment类里面,setContentType是在gridview的onclick方法里面调用的,也就是说,接下来要切换界面,于是我们通过功能逆推得到界面要改变,比如我们进入第一个switch的case

case START_FROM_LOCAL:mMainUIManager = new MyMusicManager(mActivity, this);View transView1 = mInflater.inflate(R.layout.viewpager_trans_layout, null);View contentView1 = mMainUIManager.getView(START_FROM_LOCAL);mViewPager.setVisibility(View.VISIBLE);mListViews.clear();mViewPager.removeAllViews();mListViews.add(transView1); mListViews.add(contentView1);mViewPager.setAdapter(new MyPagerAdapter(mListViews));mViewPager.setCurrentItem(1, true);break;

mMainUIManager是很关键的一个对象,类是MyMusicManager,参数是一个Activity和UIManager,activity的引用时经常传递的,第二个参数传递过去是为了使用该对象的setCurrentItem方法。

View contentView1 = mMainUIManager.getView(START_FROM_LOCAL);的作用是获取view,这个view是哪个呢?

进入到MyMusicManager里面,看到

public View getView(int from, Object object) {View contentView = mInflater.inflate(R.layout.mymusic, null);mFrom = from;mObj = object;initBg(contentView);initView(contentView);return contentView;}

进入到R.layout.mymusic里面能看到该布局就是最终的音乐列表,主界面的5个gridview item最终也是到达这个列表而找到音乐的,于是在MyMusicManager里面自然就有了给该view的一些设置,比如说点击事件,比如说音乐列表的额数据,

数据:initListView();

点击事件:在这句代码传入了该view:mUIm = new MyMusicUIManager(mActivity, mServiceManager, view,
    mUIManager);于是通过MyMusicUIManager,设置了监听事件,在该类的onClick方法里面有:

case R.id.backBtn:mUIManager.setCurrentItem();break;
这就是上面为什么要解释MyMusicManager(mActivity, this)里面传入的2个参数,第二个参数又传给了MyMusicUIManager,于是,在这里调用了mUIManager的setCurrentItem方法,于是我们终于回来了,回到了该blog开始的地方
public void setCurrentItem() {/** * 条件判断知道,现在哪个是visualbility */if (mViewPagerSub.getChildCount() > 0) {mViewPagerSub.setCurrentItem(0, true);} else {mViewPager.setCurrentItem(0, true);}}
上面的无参数方法自己通过判断有没有mViewPagerSub,来执行是返回到哪里,这还是要谈到gridview里面的5个item,其中文件夹、歌手和专辑是有子目录的,如果从文件夹的音乐列表里面返回,就是第一种情况mViewPagerSub.setCurrentItem(0,true),这样设置一个完全透明界面,但是这不影响底层的响应,这正是巧妙之处,如果说这是不是可以改进,肯定可以,这里就不试了,很显然需再把ViewPager的visualbility设置为GONE。
在这个setContentType方法里面,有两种类型的gridview item,下面的内容基本一样
                        View transView = mInflater.inflate(R.layout.viewpager_trans_layout, null);//透明布局mViewPager.setVisibility(View.VISIBLE);mListViews.clear();//清空mViewPager.removeAllViews();//清空mListViews.add(transView);mListViews.add(***View);//添加到view集合mViewPager.setAdapter(new MyPagerAdapter(mListViews));//通过adapter设置view集合到pager里面mViewPager.setCurrentItem(1, true);

功能基本就是设置ArrayList<View> 并通过Adapter设置到ViewPager,最后setCurrentItem为点击gridview 的item后显示的View。

再setContentType里面的case基本分为3类,一共8个,前2个就是直接到音乐列表,中间三个,是到文件夹歌手和专辑,最后3个是通过文件夹歌手和专辑访问音乐列表,这个需要好久才能看明白,如果我们十从歌手——>歌手列表——>音乐会经历这样一个过程:

在setContentType里面先执行case START_FROM_ARTIST:

(通过ArtistBrowserManager设置点击事件

@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {mUIManager.setContentType(ARTIST_TO_MYMUSIC, mAdapter.getItem(position));}

再执行case ARTIST_TO_MYMUSIC:
————————————————————————————————————————————————————————————————————————————
现在读者应该知道我在写这个的时候为什么前面插入了些关于架构的一些内容,软件架构设计的好与坏与代码的可读性关系密切。尽管前面的架构师的97件事现在并没有多大毛用。当然设计模式也是很关键的内容,反倒是技术却是很浅显的东西,不知道百度就能解决。
————————————————————————————————————————————————————————————————————————————

在这再区分下mViewPager和mViewPagerSub异同点,

同:这两个pager,都有2个view,并且第一个都是透明的(作者正是利用了透明的穿透性原理)。

在每次使用之前都要清空,并且清空数据源——一个ArrayList<View>,

设置显示的时候都是设置的第二个View(第一个是空白),第一个View用来返回,就是当放回的时候给pager设置为第一个透明的View,

他们第二个View都是通过一个特定的Manager获取的,最终获取到音乐列表都是通过MyMusicManager这个类获取的,

(transparent的意思就是透明的,命名的时候采用了trans,transparent的缩写。)

异:从5个gridview item进去的都是利用的是mViewPager

从文件夹,歌手,专辑进去到音乐列表的是mViewPagerSub

也就是说mViewPagerSub并不是用来装音乐列表的View容器的,只有从文件夹、歌手、专辑进去到音乐列表后会用到mViewPagerSub,这就是我一开始迷糊的地方。

mViewPagerSub就是最后3个case所使用的,从case的命名就可以大概看出来:FOLDER_TO_MYMUSIC,ARTIST_TO_MYMUSIC,ALBUM_TO_MYMUSIC



0 0