文档章节

Android Browser学习七 书签历史模块: 书签UI的实现(2)

SuShine
 SuShine
发布于 2014/03/22 16:51
字数 881
阅读 1012
收藏 2

由于书签模块还是比较复杂的, 为了不让博客变得太长, 故拆分为两篇.

上一篇介绍了书签大致的实现, 本篇主要介绍

1.书签模块BreadCrumb的实现,

2.书签模块与Activity之间的通讯, 

3. 修改添加书签的实现

开始吧:


1.书签模块BreadCrumb的实现,

这个东西其实就是在书签UI和书签添加窗口展示的那个类似windows窗口管理器的导航按钮


点击可以动态的调整书签的层级, 效果还是蛮不错的,在很多文件管理器中也有用到.

可以认为是一个自定义view (应该是一个viewgroup)了:

类图差不多是这样:可以看到有两个地方使用到了这个东西, 也就是上面截图的 书签UI和添加书签UI,

使用这个东西需要注册一个通知, 这样在用户点击BreadCrumbView的时候会回调到他们进行调整目录.

BreadCrumbView 是一个LinearLayout, 所以他里面有一个List<Crumb> 集合, Crumb里面有个view 我们看到的一连串的按钮实际上是CrumbView添加的每一个Crumb.


在BookMarkExpandableView中通过getGroupView调用到getBreadCrumbView添加每一个crumb按钮


在AddBookMarkPage 则是在View的布局中有这个View:

  mCrumbs = (BreadCrumbView) findViewById(R.id.crumbs);


BreadCrumbView的添加标签按钮和分割线的操作:

private void pushCrumb(Crumb crumb) {
        if (mCrumbs.size() > 0) {
            addSeparator();//左边添加一个分割线
        }
        mCrumbs.add(crumb);
        addView(crumb.crumbView); 
        updateVisible();
        crumb.crumbView.setOnClickListener(this);
    }

    private void addSeparator() {
        View sep = makeDividerView();
        sep.setLayoutParams(makeDividerLayoutParams());
        addView(sep);
    }

    private ImageView makeDividerView() {
        ImageView result = new ImageView(mContext);
        result.setImageDrawable(mSeparatorDrawable);
        result.setScaleType(ImageView.ScaleType.FIT_XY);
        return result;
    }

其他的就是数据库操作了, 暂时不去研究.


2.书签模块与ComboViewActivity之间的通讯, 

在使用Fragment的时候我们经常会需要fragment和activity的相互通讯, activity通知fragment比较简单, 因为fragment是activity的组成部分, 那么我们通过书签模块, 谷歌是怎么实现Fragment通知到Activity的:



其实就是

 mCallbacks = new CombinedBookmarksCallbackWrapper(
   (CombinedBookmarksCallbacks) getActivity());

真的不知道为什么要这么设计, 个人认为Activity继承一个接口, 直接cast getActivity就可以了.不清楚这个CombinedBookmarksCallbackWrapper有什么用?

3. 修改添加书签的实现

AddBookMarkPage其实有两个功能 添加书签和编辑书签,看部分onCreate的代码就知道了:


@Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        mMap = getIntent().getExtras();

        setContentView(R.layout.browser_add_bookmark);

        Window window = getWindow();

        String title = null;
        String url = null;

        mFakeTitle = (TextView) findViewById(R.id.fake_title);

        if (mMap != null) {
            Bundle b = mMap.getBundle(EXTRA_EDIT_BOOKMARK);
            if (b != null) {
                mEditingFolder = mMap.getBoolean(EXTRA_IS_FOLDER, false);
                mMap = b;
                mEditingExisting = true;
                mFakeTitle.setText(R.string.edit_bookmark);
                if (mEditingFolder) {
                    findViewById(R.id.row_address).setVisibility(View.GONE);
                } else {
                    showRemoveButton();
                }
            } else {
                int gravity = mMap.getInt("gravity", -1);
                if (gravity != -1) {
                    WindowManager.LayoutParams l = window.getAttributes();
                    l.gravity = gravity;
                    window.setAttributes(l);//不知道什么意思 这样是设置decorview的grivity
                }
            }
            title = mMap.getString(BrowserContract.Bookmarks.TITLE);
            url = mOriginalUrl = mMap.getString(BrowserContract.Bookmarks.URL);
            mTouchIconUrl = mMap.getString(TOUCH_ICON_URL);
            mCurrentFolder = mMap.getLong(BrowserContract.Bookmarks.PARENT, DEFAULT_FOLDER_ID);
        }




其实选择文件夹的窗口也在这个Activity中, 打开关闭窗口是让他们 gone 和visiable:


private void switchToFolderSelector() {
        // Set the list to the top in case it is scrolled.
        mListView.setSelection(0);
        mDefaultView.setVisibility(View.GONE);
        mFolderSelector.setVisibility(View.VISIBLE);
        mCrumbHolder.setVisibility(View.VISIBLE);
        mFakeTitleHolder.setVisibility(View.GONE);
        mAddNewFolder.setVisibility(View.VISIBLE);
        mAddSeparator.setVisibility(View.VISIBLE);
        getInputMethodManager().hideSoftInputFromWindow(
                mListView.getWindowToken(), 0);
    }



值得注意一下empty的用法:



mListView = (CustomListView) findViewById(R.id.list);
        View empty = findViewById(R.id.empty);
        mListView.setEmptyView(empty);



<LinearLayout android:id="@+id/folder_selector"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:visibility="gone"
            >

            <view class="com.android.browser.AddBookmarkPage$CustomListView"
                android:id="@+id/list"
                android:layout_marginLeft="16dip"
                android:layout_marginRight="16dip"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
            <TextView
                android:id="@+id/empty"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:visibility="gone"
                android:layout_marginLeft="16dip"
                android:layout_marginTop="16dip"
                android:text="@string/no_subfolders"
                android:textStyle="italic"
                android:textAppearance="?android:attr/textAppearanceMedium" />
        </LinearLayout>



而点击操作最终是通过BreadCrumbView来通知Activity进行获取下一级目录:



© 著作权归作者所有

SuShine
粉丝 130
博文 607
码字总数 159294
作品 0
朝阳
后端工程师
私信 提问
Android Browser学习七 书签历史模块: 书签UI的实现

浏览器的书签界面功能还是比较丰富的, 主要有 1.可以按照列表和grid两种方式展示 2.同步后会显示不同用户的书签 3.可以对书签进行拖拽 4.类似文件夹的树形层次, 类型window explorer 的地址管...

SuShine
2014/03/19
985
0
Android Browser学习二 BrowserActivity 的初始化 --其他重要模块

BrowserActivity 是浏览器的核心Activity了, 是浏览器的入口, 但是他里面并没有出来很多复杂的逻辑, 只是实现一些android 系统对activity的回调. 这些逻辑交给了Controller来处理, 就让我们一...

SuShine
2014/02/08
5.4K
0
移动平台10佳浏览器 Chrome 力压 Safari

日前美国媒体tom'shardware评选出了移动平台十佳浏览器,这份榜单是由该网站编辑评选出来的,一起来看看符不符合你的口味。 第一名 Chrome(Android, iOS) 理由:界面简约,功能友好,可以和桌...

oschina
2013/11/06
3.7K
33
Android Browser学习八 书签历史模块: 历史UI的实现

相比与书签模块, 历史模块功能比较简单, 代码很好理解,很值得学习其架构实现, 我们就从代码层面来讲解其实现, 希望其中的一些东西对将来的开发有帮助. 首先是onCreate: @Override onCreat...

SuShine
2014/03/23
1K
0
Android Browser学习〇 为什么要学习Android Browser代码

Browser的代码总算是看的差不多了,但是给我最大的感觉还是,乱.可能是我能力不够?但是说实话却是乱,结构混乱,感觉和OSC客户端的代码差距不少.感觉是一个哥们信手敲出来的,前期没什么规划什么的...

SuShine
2014/02/08
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

关于运维,该怎么决定它的方向,这个似工作又似兴趣的存在

我之前主要从事网络、桌面、机房管理等相关工作,这些工作使我迷惘,这应该是大多数运维人都经历过的过程; 18年国庆,我从国内前三的消费金融公司裸辞,下海创业,就是想要摆脱这样的困境。...

网络小虾米
19分钟前
4
0
Java Timer的用法

Timer timer = new Timer(); timer.schedule(new TimerTask() { public void run() { System.out.println("11232"); } }, 200000 , 1000); public void schedule(TimerTask task, long delay......

林词
23分钟前
4
0
使用js动态加载外部js文件以及动态创建script脚本

动态脚本指的是在页面加载时不存在,但将来的某一时刻通过修改该DOM动态添加的脚本。和操作HTML元素一样,创建动态脚本也有两种方式:插入外部文件和直接插入JavaScript代码。 动态加载外的外...

Bing309
30分钟前
3
0
从零开始入门 K8s | Kubernetes 网络概念及策略控制

作者 | 阿里巴巴高级技术专家 叶磊 一、Kubernetes 基本网络模型 本文来介绍一下 Kubernetes 对网络模型的一些想法。大家知道 Kubernetes 对于网络具体实现方案,没有什么限制,也没有给出特...

阿里巴巴云原生
34分钟前
3
0
天气获取

本文转载于:专业的前端网站➨天气获取 $.get("http://wthrcdn.etouch.cn/WeatherApi", { citykey: cityCode }, function (d) { //创建文档对象 var parser = new ......

前端老手
34分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部