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

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

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

1.书签模块BreadCrumb的实现,

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

3. 修改添加书签的实现

开始吧:


1.书签模块BreadCrumb的实现,

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

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

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


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

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

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

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

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

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


在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的:

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


其实就是

 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进行获取下一级目录:


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


你可能感兴趣的:(Android Browser学习七 书签历史模块: 书签UI的实现(2))