zoukankan      html  css  js  c++  java
  • 揭秘uc浏览器二

    这节,四个议题:

    ①一个网页显示在webview控件中

    ②如何正常隐藏显示标题栏。

    ③如何用runnable来隐藏标题栏,这样子就更加的专业化。

    ④上节我们说道了QuickActionGrid,看他长得怎么样。

    如何显示webview控件了,This is a question?这个除了上面的文章的支持外,主要是这个updateUI的方法。

    /**
         * Update the UI: Url edit text, previous/next button state,...
         */
        private void updateUI() {
            mUrlEditText.removeTextChangedListener(mUrlTextWatcher);
            mUrlEditText.setText(mCurrentWebView.getUrl());
            mUrlEditText.addTextChangedListener(mUrlTextWatcher);
            
            mPreviousButton.setEnabled(mCurrentWebView.canGoBack());
            mNextButton.setEnabled(mCurrentWebView.canGoForward());
            
            if (mCurrentWebView.getUrl() != null)
                mRemoveTabButton.setEnabled((mViewFlipper.getChildCount() > 1 || !mCurrentWebView.getUrl().equals(Constants.URL_ABOUT_START)));
            else
                mRemoveTabButton.setEnabled(mViewFlipper.getChildCount() > 1);
            
            mProgressBar.setProgress(mCurrentWebView.getProgress());
            
            updateGoButton();
            
            updateTitle();
            
            updateFavIcon();
        }
        

    这段代码是如此的熟悉,我们也来总结总结:

    ①我们需要更新URL文本框的数据,添加新的事件的监听。

    ②把前一步,后一步按钮设置是否禁用。

    ③把移去按钮,设置是否禁用。

    ④把进度条进度进行更新。

    ⑤更新去哪儿的按钮

    ⑥更新相应的标题

    ⑦更新相应的图标

    这个webview视图进行显示了,相应视图也进行更新了。

    如何正常显示标题栏,这个就是updateTitle方法做的事情,来瞧一瞧:

        /**
         * Update the application title.
         */
        private void updateTitle() {
            String value = mCurrentWebView.getTitle();
            
            if ((value != null) &&
                    (value.length() > 0)) {        
                this.setTitle(String.format(getResources().getString(R.string.ApplicationNameUrl), value));            
            } else {
                clearTitle();
            }
        }

    这是一个更新标题的方法,我们可以得出来相应总结,

    ①我们可以获取当前webview的标题,如果是标题不为空的话,我们就设置相应的标题。否则就清空标题.

    正常的隐藏标题栏,极大提高了用户体验,这是一个runnable接口功劳,那具体怎么做了:

     1 /**
     2      * Start a runnable to hide the tool bars after a user-defined delay.
     3      */
     4     private void startToolbarsHideRunnable() {
     5                         
     6         if (mHideToolbarsRunnable != null) {
     7             mHideToolbarsRunnable.setDisabled();
     8         }
     9         
    10         int delay = Integer.parseInt(Controller.getInstance().getPreferences().getString(Constants.PREFERENCES_GENERAL_BARS_DURATION, "3000"));
    11         if (delay <= 0) {
    12             delay = 3000;
    13         }
    14         
    15         mHideToolbarsRunnable = new HideToolbarsRunnable(this, delay);        
    16         new Thread(mHideToolbarsRunnable).start();
    17     }
    18     
    19     /**
    20      * Hide the tool bars.
    21      */
    22     public void hideToolbars() {
    23         if (mUrlBarVisible) {            
    24             if ((!mUrlEditText.hasFocus()) &&
    25                     (!mToolsActionGridVisible)) {
    26                 
    27                 if (!mCurrentWebView.isLoading()) {
    28                     setToolbarsVisibility(false);
    29                 }
    30             }
    31         }
    32         mHideToolbarsRunnable = null;
    33     }

    我这里能够得到这样的提示了:

    ①用到sharedpreference看用户设置时间,如果没有设置时间的话,默认是3秒就开启一条线程将其标题栏隐藏了。为什么会用到多线程了,这样不会更新主界面造成卡顿的现象。

    ②如果toolbar是隐藏的,就将其隐藏。

    QuickActionGrid是一个自定义控件,为什么用自定义控件了,

    ①android自带的控件太多bug。

    ②自定义控件也非常的灵活。

    源代码如下:

    public class QuickActionGrid extends QuickActionWidget {
    
    //    grid 控件
        private GridView mGridView;
    
        /**
         * grid 构造函数  数据的初始化
         * @param context  上下文对象
         */
        public QuickActionGrid(Context context) {
            super(context);
    
            setContentView(R.layout.gd_quick_action_grid);
    
            final View v = getContentView();
            mGridView = (GridView) v.findViewById(R.id.gdi_grid);
        }
        /**
         * 弹出相应的action的方法
         */
    
        @Override
        protected void populateQuickActions(final List<QuickAction> quickActions) {
    
            mGridView.setAdapter(new BaseAdapter() {
    
                public View getView(int position, View view, ViewGroup parent) {
    
                    TextView textView = (TextView) view;
    
                    if (view == null) {
                        final LayoutInflater inflater = LayoutInflater.from(getContext());
                        textView = (TextView) inflater.inflate(R.layout.gd_quick_action_grid_item, mGridView, false);
                    }
    
                    QuickAction quickAction = quickActions.get(position);
                    textView.setText(quickAction.mTitle);
                    textView.setCompoundDrawablesWithIntrinsicBounds(null, quickAction.mDrawable, null, null);
    
                    return textView;
    
                }
    
                public long getItemId(int position) {
                    return position;
                }
    
                public Object getItem(int position) {
                    return null;
                }
    
                public int getCount() {
                    return quickActions.size();
                }
            });
    
            mGridView.setOnItemClickListener(mInternalItemClickListener);
        }
    
        /**
         * 尺寸改变的事件
         */
        @Override
        protected void onMeasureAndLayout(Rect anchorRect, View contentView) {
    
            contentView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            contentView.measure(MeasureSpec.makeMeasureSpec(getScreenWidth(), MeasureSpec.EXACTLY),
                    LayoutParams.WRAP_CONTENT);
    
            int rootHeight = contentView.getMeasuredHeight();
    
            int offsetY = getArrowOffsetY();
            int dyTop = anchorRect.top;
            int dyBottom = getScreenHeight() - anchorRect.bottom;
    
            boolean onTop = (dyTop > dyBottom);
            int popupY = (onTop) ? anchorRect.top - rootHeight + offsetY : anchorRect.bottom - offsetY;
    
            setWidgetSpecs(popupY, onTop);
        }
    
        /**
         * 每项点击的事件
         */
        private OnItemClickListener mInternalItemClickListener = new OnItemClickListener() {
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                getOnQuickActionClickListener().onQuickActionClicked(QuickActionGrid.this, position);
                if (getDismissOnClick()) {
                    dismiss();
                }
            }
        };
    
    }

    这个quickGrid控件是继承与quickWidget控件,这也是一个自定义控件。对于他这个方法,我们集中于populateQuickActions方法和onMeasureAndLayout方法。

    ①populateQuickActions方法其实就是一个填充相应数据的方法,就是把相应的数据通过baseAdapter填充与gridview控件,gridview控件用于显示相应数据项。

    ②mInternalItemClickListener方法了,就是为每一个item赋予点击事件,如果这个点击动作已经执行以后,就相应弹出的popwindow就进行了隐藏。

    quickwidget控件在这个项目用的很多,这是许多控件的基类,怎么写的。

      1     private static final int MEASURE_AND_LAYOUT_DONE = 1 << 1;
      2 
      3     private final int[] mLocation = new int[2];
      4     private final Rect mRect = new Rect();
      5 
      6     private int mPrivateFlags;
      7 
      8     private Context mContext;
      9 
     10     private boolean mDismissOnClick;
     11     private int mArrowOffsetY;
     12 
     13     private int mPopupY;
     14     private boolean mIsOnTop;
     15 
     16     private int mScreenHeight;
     17     private int mScreenWidth;
     18     private boolean mIsDirty;
     19 
     20     private OnQuickActionClickListener mOnQuickActionClickListener;
     21     private ArrayList<QuickAction> mQuickActions = new ArrayList<QuickAction>();
     22 
     23     /**
     24      * Interface that may be used to listen to clicks on quick actions.
     25      *
     26      * @author Benjamin Fellous
     27      * @author Cyril Mottier
     28      */
     29     public static interface OnQuickActionClickListener {
     30         /**
     31          * Clients may implement this method to be notified of a click on a
     32          * particular quick action.
     33          *
     34          * @param position Position of the quick action that have been clicked.
     35          */
     36         void onQuickActionClicked(QuickActionWidget widget, int position);
     37     }
     38 
     39     /**
     40      * Creates a new QuickActionWidget for the given context.
     41      *
     42      * @param context The context in which the QuickActionWidget is running in
     43      */
     44     public QuickActionWidget(Context context) {
     45         super(context);
     46 
     47         mContext = context;
     48 
     49         initializeDefault();
     50 
     51         setFocusable(true);
     52         setTouchable(true);
     53         setOutsideTouchable(true);
     54         setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
     55         setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
     56 
     57         final WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
     58         mScreenWidth = windowManager.getDefaultDisplay().getWidth();
     59         mScreenHeight = windowManager.getDefaultDisplay().getHeight();
     60     }
     61 
     62     /**
     63      * Equivalent to {@link PopupWindow#setContentView(View)} but with a layout
     64      * identifier.
     65      *
     66      * @param layoutId The layout identifier of the view to use.
     67      */
     68     public void setContentView(int layoutId) {
     69         setContentView(LayoutInflater.from(mContext).inflate(layoutId, null));
     70     }
     71 
     72     private void initializeDefault() {
     73         mDismissOnClick = true;
     74         mArrowOffsetY = mContext.getResources().getDimensionPixelSize(R.dimen.gd_arrow_offset);
     75     }
     76 
     77     /**
     78      * Returns the arrow offset for the Y axis.
     79      *
     80      * @see {@link #setArrowOffsetY(int)}
     81      * @return The arrow offset.
     82      */
     83     public int getArrowOffsetY() {
     84         return mArrowOffsetY;
     85     }
     86 
     87     /**
     88      * Sets the arrow offset to a new value. Setting an arrow offset may be
     89      * particular useful to warn which view the QuickActionWidget is related to.
     90      * By setting a positive offset, the arrow will overlap the view given by
     91      * {@link #show(View)}. The default value is 5dp.
     92      *
     93      * @param offsetY The offset for the Y axis
     94      */
     95     public void setArrowOffsetY(int offsetY) {
     96         mArrowOffsetY = offsetY;
     97     }
     98 
     99     /**
    100      * Returns the width of the screen.
    101      *
    102      * @return The width of the screen
    103      */
    104     protected int getScreenWidth() {
    105         return mScreenWidth;
    106     }
    107 
    108     /**
    109      * Returns the height of the screen.
    110      *
    111      * @return The height of the screen
    112      */
    113     protected int getScreenHeight() {
    114         return mScreenHeight;
    115     }
    116 
    117     /**
    118      * By default, a {@link QuickActionWidget} is dismissed once the user
    119      * clicked on a {@link QuickAction}. This behavior can be changed using this
    120      * method.
    121      *
    122      * @param dismissOnClick True if you want the {@link QuickActionWidget} to
    123      * be dismissed on click else false.
    124      */
    125     public void setDismissOnClick(boolean dismissOnClick) {
    126         mDismissOnClick = dismissOnClick;
    127     }
    128 
    129     public boolean getDismissOnClick() {
    130         return mDismissOnClick;
    131     }
    132 
    133     /**
    134      * @param listener
    135      */
    136     public void setOnQuickActionClickListener(OnQuickActionClickListener listener) {
    137         mOnQuickActionClickListener = listener;
    138     }
    139 
    140     /**
    141      * Add a new QuickAction to this {@link QuickActionWidget}. Adding a new
    142      * {@link QuickAction} while the {@link QuickActionWidget} is currently
    143      * being shown does nothing. The new {@link QuickAction} will be displayed
    144      * on the next call to {@link #show(View)}.
    145      *
    146      * @param action The new {@link QuickAction} to add
    147      */
    148     public void addQuickAction(QuickAction action) {
    149         if (action != null) {
    150             mQuickActions.add(action);
    151             mIsDirty = true;
    152         }
    153     }
    154 
    155     /**
    156      * Removes all {@link QuickAction} from this {@link QuickActionWidget}.
    157      */
    158     public void clearAllQuickActions() {
    159         if (!mQuickActions.isEmpty()) {
    160             mQuickActions.clear();
    161             mIsDirty = true;
    162         }
    163     }
    164 
    165     /**
    166      * Call that method to display the {@link QuickActionWidget} anchored to the
    167      * given view.
    168      *
    169      * @param anchor The view the {@link QuickActionWidget} will be anchored to.
    170      */
    171     public void show(View anchor) {
    172 
    173         final View contentView = getContentView();
    174 
    175         if (contentView == null) {
    176             throw new IllegalStateException("You need to set the content view using the setContentView method");
    177         }
    178 
    179         // Replaces the background of the popup with a cleared background
    180         setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    181 
    182         final int[] loc = mLocation;
    183         anchor.getLocationOnScreen(loc);
    184         mRect.set(loc[0], loc[1], loc[0] + anchor.getWidth(), loc[1] + anchor.getHeight());
    185 
    186         if (mIsDirty) {
    187             clearQuickActions();
    188             populateQuickActions(mQuickActions);
    189         }
    190 
    191         onMeasureAndLayout(mRect, contentView);
    192 
    193         if ((mPrivateFlags & MEASURE_AND_LAYOUT_DONE) != MEASURE_AND_LAYOUT_DONE) {
    194             throw new IllegalStateException("onMeasureAndLayout() did not set the widget specification by calling"
    195                     + " setWidgetSpecs()");
    196         }
    197 
    198         showArrow();
    199         prepareAnimationStyle();
    200         showAtLocation(anchor, Gravity.NO_GRAVITY, 0, mPopupY);
    201     }
    202 
    203     protected void clearQuickActions() {
    204         if (!mQuickActions.isEmpty()) {
    205             onClearQuickActions();
    206         }
    207     }
    208 
    209     protected void onClearQuickActions() {
    210     }
    211 
    212     protected abstract void populateQuickActions(List<QuickAction> quickActions);
    213 
    214     protected abstract void onMeasureAndLayout(Rect anchorRect, View contentView);
    215 
    216     protected void setWidgetSpecs(int popupY, boolean isOnTop) {
    217         mPopupY = popupY;
    218         mIsOnTop = isOnTop;
    219 
    220         mPrivateFlags |= MEASURE_AND_LAYOUT_DONE;
    221     }
    222 
    223     private void showArrow() {
    224 
    225         final View contentView = getContentView();
    226         final int arrowId = mIsOnTop ? R.id.gdi_arrow_down : R.id.gdi_arrow_up;
    227         final View arrow = contentView.findViewById(arrowId);
    228         final View arrowUp = contentView.findViewById(R.id.gdi_arrow_up);
    229         final View arrowDown = contentView.findViewById(R.id.gdi_arrow_down);
    230 
    231         if (arrowId == R.id.gdi_arrow_up) {
    232             arrowUp.setVisibility(View.VISIBLE);
    233             arrowDown.setVisibility(View.INVISIBLE);
    234         } else if (arrowId == R.id.gdi_arrow_down) {
    235             arrowUp.setVisibility(View.INVISIBLE);
    236             arrowDown.setVisibility(View.VISIBLE);
    237         }
    238 
    239         ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) arrow.getLayoutParams();
    240         param.leftMargin = mRect.centerX() - (arrow.getMeasuredWidth()) / 2;
    241     }
    242 
    243     private void prepareAnimationStyle() {
    244 
    245         final int screenWidth = mScreenWidth;
    246         final boolean onTop = mIsOnTop;
    247         final int arrowPointX = mRect.centerX();
    248 
    249         if (arrowPointX <= screenWidth / 4) {
    250             setAnimationStyle(onTop ? R.style.GreenDroid_Animation_PopUp_Left
    251                     : R.style.GreenDroid_Animation_PopDown_Left);
    252         } else if (arrowPointX >= 3 * screenWidth / 4) {
    253             setAnimationStyle(onTop ? R.style.GreenDroid_Animation_PopUp_Right
    254                     : R.style.GreenDroid_Animation_PopDown_Right);
    255         } else {
    256             setAnimationStyle(onTop ? R.style.GreenDroid_Animation_PopUp_Center
    257                     : R.style.GreenDroid_Animation_PopDown_Center);
    258         }
    259     }
    260 
    261     protected Context getContext() {
    262         return mContext;
    263     }
    264 
    265     protected OnQuickActionClickListener getOnQuickActionClickListener() {
    266         return mOnQuickActionClickListener;
    267     }

    首先这个控件本质是Popwindow,对于这个控件我们要探讨的有这么几点:

    ①show这个方法中了,主要是根据相应的锚基点来弹出来了,并且在指定的位置弹出相应的窗口。

    ②在showarrow这个方法,我们需要根据是否向上还是向下显示相应的箭头,给用户一个很好的提示。

    ③在动画的操作方法中,我们要根据其坐标是否小于全频宽度的四分之一位置,从左边的位置弹出来,其坐标从全频宽度四分之三的位置,从右侧位置弹出来了。

    有了这篇文章介绍,主界面应该了解了把?下节介绍收藏和历史界面。

  • 相关阅读:
    JS站点
    1011 World Cup Betting (20分)
    1007 Maximum Subsequence Sum (25分)(动态规划DP)
    1006 Sign In and Sign Out (25分)
    1005 Spell It Right (20分)
    1004 Counting Leaves (30分)(DFS)
    1003 Emergency (25分)(Dijkstra算法)
    1002 A+B for Polynomials (25分)
    1001 A+B Format (20分)
    canvas
  • 原文地址:https://www.cnblogs.com/manuosex/p/3613319.html
Copyright © 2011-2022 走看看