Gallery的整体架构

1.       Gallery主要的功能是实现本地存储器,MTP存储器和网络中的媒体(图像和视频)的浏览,

显示,操作(删除,分享,合成,选择和缩放等)。

下面的图来描述Gallery的职责:




Data Manager: 管理数据源,数据源包括: Uri连接数据,本地数据,Gmail同步数据,MTP传输数据,排序后的数据,过滤后的数据,加密数据,由客户自己添加的的数据,只包含一个资源的数据。这些数据源都有共同的基类: MediaSource。数据源由DataManager.java类负责管理。

 

显示的界面有:AlbumSetPage(相册缩略图), AlbumPage(单个相册的照片缩略图),PhotoPage(单个相片缩略图)。这些界面的父类为ActivityState.java,界面切换由StateManager.java负责。


Gallery常见浏览模式有:

1.AlbumSetPage模式: 相册集模式,即用户进入Gallery应用首先看到的相册模式,相册一般把相册集合的第一张照片作为封面图,在SD,内置内存卡,有图片和视频就会显示出来,那么依据什么来划分图像文件属于同一个相册集,相同目录和同样类型的图像文件属于同一个相册。

2.AlumPage模式: 点击了某个相册,进入AlbumPage模式,即包含一个目录的所有image 和video文件。此模式下可以浏览一个相册集所有的图像文件。

3.photoPage模式: 浏览相片和播放影片模式,这里具体到MediaItem。 点击某个图像文件,如果是相片用photo view来浏览,是video

文件则需要调用播放器来播放视频。

 注意: 当AlbumSetPage只有一个item时,点击相册集会直接进入幻灯片模式。


图片浏览界面切换源码分析:

点击Gallery图标默认的界面是进入AlbumSetPage显示的界面,Gallery为主要界面的入口点。所有先从Gallery这个类来分析代码:

进入AlbumSetPage图库模式

protected void onCreate(Bundle savedInstanceState) {

        setContentView(R.layout.main);   // 主界面

        if (savedInstanceState != null) {

            getStateManager().restoreFromState(savedInstanceState); // 有保存状态信息

        } else {

            initializeByIntent();  // 初始化处理action

        }

    }

 

 

 

private void initializeByIntent() {

        ...

         else {

            startDefaultPage();// 从桌面进入Gallery, 一般处理

        }

}

 

进入 startDefaultPage()方法:

 

public void startDefaultPage() {

        PicasaSource.showSignInReminder(this);

        Bundle data = new Bundle();

        data.putString(AlbumSetPage.KEY_MEDIA_PATH,

                getDataManager().getTopSetPath(DataManager.INCLUDE_ALL));

        // 包含Image 和Video文件

 

        //add for DRM feature

        if (MediatekFeature.isDrmSupported()) {

            //when start default page, we query all drm media, any risk???

            Log.d(TAG,"startDefaultPage:we query all drm media");

            data.putInt(OmaDrmStore.DrmExtra.EXTRA_DRM_LEVEL,

                        OmaDrmStore.DrmExtra.DRM_LEVEL_ALL);

        }//

 

        if (MediatekFeature.isStereoDisplaySupported()) {

            if (null != getIntent().getExtras()) {

                data.putBoolean(StereoHelper.STEREO_EXTRA,

                      getIntent().getExtras().getBoolean(

                                                  StereoHelper.STEREO_EXTRA,false));

            }

        }

 

// 切换到AlbumSetPage界面。

       // 上面提到界面是用StateManager来管理的。

        getStateManager().startState(AlbumSetPage.class, data);

        mVersionCheckDialog = PicasaSource.getVersionCheckDialog(this);

        if (mVersionCheckDialog != null) {

            mVersionCheckDialog.setOnCancelListener(this);

        }

    }



进AlbumPage相册浏览模式


上面的getStateManager().startState(AlbumSetPage.class,data);

完成AlbumSetPager界面类的切换。下面来分析

StateManager.java startState方法


StateManager.java

public void startState(Class<? extends ActivityState> klass,

            Bundle data) {

              ActivityState state = null;

        try {

            state = klass.newInstance(); // 新建一个实例

        } catch (Exception e) {

            throw new AssertionError(e);

        }

        // 采用stack栈来管理页面逻辑切换。

        if (!mStack.isEmpty()) {

            ActivityState top = getTopState();

            top.transitionOnNextPause(top.getClass(), klass,

                    StateTransitionAnimation.Transition.Incoming);

            if (mIsResumed) top.onPause();

        }

        state.initialize(mActivity, data);

        mStack.push(new StateEntry(data, state));  // 压栈

        state.onCreate(data, null);   // AlbumSetPage.onCreate();

        if (mIsResumed) state.resume();

    }

 




…. 到这里就会显示相册集缩略图(AlbumSetPage) 这里注意的是;

AlbumSetPage并不是一个界面显示的类, 因为Gallery显示界面只有一个Activity,里面的界面都是用OpengL画出来的,而AlbumSetPage这是界面显示的逻辑部分,界面的切换跟数据逻辑绑定在一起的。

因为Gallery采用了MVC的架构。如图所示;



当我们点击某个相册时候,opengl就会检测到点击了那个相册,然后分发消息交给AlbumSetPage界面逻辑类来处理。

处理过程如下:

StateManager.java

public void startState(Class<? extends ActivityState> klass,

            Bundle data) {

              ActivityState state = null;

        try {

            state = klass.newInstance(); // 新建一个实例

        } catch (Exception e) {

            throw new AssertionError(e);

        }

        // 采用stack栈来管理页面逻辑切换。

        if (!mStack.isEmpty()) {

            ActivityState top = getTopState();

            top.transitionOnNextPause(top.getClass(), klass,

                    StateTransitionAnimation.Transition.Incoming);

            if (mIsResumed) top.onPause();

        }

        state.initialize(mActivity, data);

        mStack.push(new StateEntry(data, state));  // 压栈

        state.onCreate(data, null);   // AlbumSetPage.onCreate();

        if (mIsResumed) state.resume();

    }

 

public void onSingleTapUp(int slotIndex) {  // slotIndex代表相册的调试,一般0代表第一个相册

        if (!mIsActive) return;

               // 当进入选择模式时

        if (mSelectionManager.inSelectionMode()) {

            MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);

            if (targetSet == null) return; // Content is dirty, we shall reload soon

            mSelectionManager.toggle(targetSet.getPath());

            mSlotView.invalidate();

        } else {

            // Show pressed-up animation for the single-tap.

            mAlbumSetView.setPressedIndex(slotIndex); // 手指点击相册的动画

            mAlbumSetView.setPressedUp();

            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PICK_ALBUM, slotIndex, 0),

                    FadeTexture.DURATION);  // 发送消息

        }

    }

 

…….

mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {

            @Override

            public void handleMessage(Message message) {

                switch (message.what) {

                    case MSG_PICK_ALBUM: { // 这里处理消息,跳转到                                               pickAlbum方法处理

                        pickAlbum(message.arg1);

                        break;

                 ……..

        };

 

 

// pickAlbum 的方法

private void pickAlbum(int slotIndex) {

        if (!mIsActive) return;

 

        MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);

               // 得到相册集的标识

          ….

        String mediaPath = targetSet.getPath().toString(); // 得到相册的路径path

        if (mGetAlbum && targetSet.isLeafAlbum()) {….离开albusetPage

          

        } else if (targetSet.getSubMediaSetCount() > 0) {

            data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);

                //add for DRM feature: pass drm inclusio info to next ActivityState

                if (IS_DRM_SUPPORTED || IS_STEREO_DISPLAY_SUPPORTED) {

                    data.putInt(DrmHelper.DRM_INCLUSION, mMtkInclusion);

                }// 是否显示相应的drm文件

            mActivity.getStateManager().startStateForResult(

                    AlbumSetPage.class, REQUEST_DO_ANIMATION, data);

        } else {

           ……….

            }

            data.putString(AlbumPage.KEY_MEDIA_PATH, mediaPath);

            mActivity.getStateManager().startStateForResult(

                    AlbumPage.class, REQUEST_DO_ANIMATION, data);

                      // 进入AlbumPage模式(即可以浏览该相册下的图像和视频文件缩略图)

        }

    }

 


进入PhotoPage单个相片浏览模式


以上的代码就进去了AlbumPage 浏览缩略图模式。

当单击某个相片的缩略图,就会浏览该相片,处理过程与AlbumSetPage类似。

请看以下代码:

 

AlbumPage类:

private void onSingleTapUp(int slotIndex)  {

mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PICK_PHOTO, slotIndex, 0),

                    FadeTexture.DURATION); // 发送消息

    }

 

mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {

            @Override

            public void handleMessage(Message message) {

                switch (message.what) {

                    case MSG_PICK_PHOTO: {

                        pickPhoto(message.arg1);

                             ……

    }

 

pickPhoto 方法;

 

private void pickPhoto(int slotIndex, boolean startInFilmstrip) {

          if (!startInFilmstrip) {

                             // 不是幻灯片模式

            // Launch photos in lights out mode

            mActivity.getGLRoot().setLightsOutMode(true);

        }

 

        MediaItem item = mAlbumDataAdapter.get(slotIndex);// 得到相片的标识

        if (item == null) return; // Item not ready yet, ignore the click

        if (mGetContent) {

            onGetContent(item); // 通过彩信进来

        } else if (mLaunchedFromPhotoPage) { // 通过图片浏览模式进来

            ……..

            onBackPressed();

        } else {

            ……………..

            if (startInFilmstrip) {// 如果只有相册只有一张照片,直接进入幻灯片                                                            模式

                mActivity.getStateManager().switchState(this, PhotoPage.class, data);

            } else {

                                       // 浏览相片模式

                mActivity.getStateManager().startStateForResult(

                            PhotoPage.class, REQUEST_PHOTO, data);

 


PhotoView单个相片浏览显示界面

PhotoPage类:


public void onCreate(Bundle data, Bundle restoreState) {

……

  mPhotoView = new PhotoView(mActivity); // 图片显示的类,opengl

        mPhotoView.setListener(this); // 设置监听

。。。。。。

mRootPane.addComponent(mPhotoView);// 把显示图片界面添加到画布组件

}

 


到这里,基本的图片浏览过程基本完成了。

Gallery 调用图片浏览整体调用流程图。


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
package e gallery; import android app Activity; import android os Bundle; import android view LayoutInflater; import android view View; import android view ViewGroup; import android view ViewGroup MarginLayoutParams; import android widget AdapterView; import android widget AdapterView OnItemSelectedListener; import android widget BaseAdapter; import android widget Gallery; import android widget ImageView; import e gallery R; public class MainActivity extends Activity implements OnItemSelectedListener { Gallery gallery; ImageView main imageView; ImageView picture imageView; Gesture+ gesture; int[] ids1 { R drawable b R drawable c R drawable d R drawable f R drawable g }; @Override protected void onCreate Bundle savedInstanceState { super onCreate savedInstanceState ; setContentView R layout main ; main imageView ImageView findViewById R id main imageView ; gallery Gallery findViewById R id gallery ; gallery setOnItemSelectedListener this ; 怎么设置从中间开始 gallery setAdapter new MyAdapter ; } class MyAdapter extends BaseAdapter{ @Override public int getCount { return Integer MAX VALUE; } @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 { LayoutInflater layoutInflater LayoutInflater from MainActivity this ; convertView layoutInflater inflate R layout picture null ; picture imageView ImageView convertView findViewById R id picture imageView ; picture imageView setImageResource ids1[position % 5] ; return convertView; } } @Override public void onItemSelected AdapterView< > parent View view int position long id { main imageView setImageResource ids1[position % 5] ; } @Override public void onNothingSelected AdapterView< > parent { } }">package e gallery; import android app Activity; import android os Bundle; import android view LayoutInflater; import android view View; import android view ViewGroup; import android view ViewGroup MarginLayoutParams; import android widget AdapterView; import android widget AdapterView OnItemSelecte [更多]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值