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

    首先,看一下项目完成后的,最终效果是这样的:

    一.主界面

    二,书签界面

    三、主界面

    四.操作对话框界面

    这几个界面你是否看到了uc浏览器的影子了,其实我说你也可以了,在接下来篇幅中,我将手把手叫大家完成这个浏览器。

    首先,我们从主界面开始吧,这是一个主线,项目的一些开始由他开始了。

     从图一中,我们可以看出其布局文件主要的布局文件以线性布局为主,而同时了他嵌套了相对布局,有图有真相,下图就是我对主页布局文件一种说明:

    从上图的布局文件,我们可以清晰的看出来了,中间viewflipper这个翻页控件有大作用的,里面的一些网页内容将展现如此。

    android布局文件固然重要,但只有了代码控制,才能使一个app变得"有血有肉",我们来看看这个主页面的控制文件。

    照例了,我们先介绍了一些常量的声明:这些在下面的代码中将会大量的使用,源代码如下:

    //滑动像素的入口常量
        private static final int FLIP_PIXEL_THRESHOLD = 200;
        //滑动时间的入口常量
        private static final int FLIP_TIME_THRESHOLD = 400;
    //    添加标签的菜单常量
        private static final int MENU_ADD_BOOKMARK = Menu.FIRST;
    //展示标签的菜单常量
        private static final int MENU_SHOW_BOOKMARKS = Menu.FIRST + 1;
    //展示下载的菜单常量
        private static final int MENU_SHOW_DOWNLOADS = Menu.FIRST + 2;    
    //喜爱的菜单常量
        private static final int MENU_PREFERENCES = Menu.FIRST + 3;
    //退出的菜单常量
        private static final int MENU_EXIT = Menu.FIRST + 4;    
    //打开的上下文菜单常量    
        private static final int CONTEXT_MENU_OPEN = Menu.FIRST + 10;
    //打开新的菜单常量
        private static final int CONTEXT_MENU_OPEN_IN_NEW_TAB = Menu.FIRST + 11;
    //下载的上下文菜单常量
        private static final int CONTEXT_MENU_DOWNLOAD = Menu.FIRST + 12;
    //拷贝的菜单常量
        private static final int CONTEXT_MENU_COPY = Menu.FIRST + 13;
    //发送具体的上下文菜单常量
        private static final int CONTEXT_MENU_SEND_MAIL = Menu.FIRST + 14;
    //分享上下文菜单常量
        private static final int CONTEXT_MENU_SHARE = Menu.FIRST + 15;
    //打开标签历史记录的页面常量    
        private static final int OPEN_BOOKMARKS_HISTORY_ACTIVITY = 0;
    //打开下载的页面常量
        private static final int OPEN_DOWNLOADS_ACTIVITY = 1;
    //打开文件选择的界面的常量
        private static final int OPEN_FILE_CHOOSER_ACTIVITY = 2;
        
        //全频的常量
        protected static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
                new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);

    观察上面各个变量,我们可以得出来这样的结论:

    ①程序将会利用一些菜单,上下文菜单进行添加书签,书签,退出的操作。

    ②主界面全屏形式将会大量利用。

    接下来,是一些控件变量的声明,源代码如下:

    //    填充器
        protected LayoutInflater mInflater = null;
    //顶部的线性布局文件    
        private LinearLayout mTopBar;
    //底部 线性布局文件     
        private LinearLayout mBottomBar;
        
        private LinearLayout mFindBar;
    //前一步按钮    
        private ImageButton mFindPreviousButton;
    //下一步按钮    
        private ImageButton mFindNextButton;
    //关闭的按钮
        private ImageButton mFindCloseButton;
    //文本框    
        private EditText mFindText;
    //前一步视图    
        private ImageView mPreviousTabView;
    //下一步的视图
        private ImageView mNextTabView;
    //工具按钮    
        private ImageButton mToolsButton;
    //自动匹配文本框    
        private AutoCompleteTextView mUrlEditText;
    //前往的按钮
        private ImageButton mGoButton;
    //进度条    
        private ProgressBar mProgressBar;    
    //右边imageviw    
        private ImageView mBubbleRightView;
    //左边的imageview
        private ImageView mBubbleLeftView;
    //当前的web视图    
        private CustomWebView mCurrentWebView;
    //所有的打开的web的视图    
        private List<CustomWebView> mWebViews;
    //前面按钮    
        private ImageButton mPreviousButton;
    //下一步的按钮    
        private ImageButton mNextButton;
        //开启一个tab按钮
        private ImageButton mNewTabButton;
        //移去tab的按钮
        private ImageButton mRemoveTabButton;
        //快速进入的按钮
        private ImageButton mQuickButton;
        //当前的背景
        private Drawable mCircularProgress;
        //url 是否显示
        private boolean mUrlBarVisible;
        //工具grid 是否显示
        private boolean mToolsActionGridVisible = false;
        //对话框是否显示
        private boolean mFindDialogVisible = false;
        //url的监听者
        private TextWatcher mUrlTextWatcher;
        //开启的多线程
        private HideToolbarsRunnable mHideToolbarsRunnable;
        //翻页的控件
        private ViewFlipper mViewFlipper;
        //手势的监听者
        private GestureDetector mGestureDetector;
        
        //换tab的枚举
        private SwitchTabsMethod mSwitchTabsMethod = SwitchTabsMethod.BOTH;
        //action的grid
        private QuickActionGrid mToolsActionGrid;
        //消息URL
        private ValueCallback<Uri> mUploadMessage;
        //改变的监听者
        private OnSharedPreferenceChangeListener mPreferenceChangeListener;
        
        private View mCustomView;
        //当前的
        private Bitmap mDefaultVideoPoster = null;
        
        private View mVideoProgressView = null;
        //桢不具
        private FrameLayout mFullscreenContainer;    
        //相应回调
        private WebChromeClient.CustomViewCallback mCustomViewCallback;
        //改变tab的枚举
        private enum SwitchTabsMethod {
            BUTTONS,
            FLING,
            BOTH
        }
        

    通过上述一些变量的声明,我们应该明白这么几点了

    ①主要控件声明是一些上局布局文件中的控件的声明。

    ②取此之外,一些判断其是否显示隐藏的变量,一些保存当前webview的变量,一些保存当前webview视图也在此申明了,相应回调的接口。

    ③此外,还有一个tab页改变方式的申明。

    接下来,重头戏——方法实现就来了。首先是一个oncreate方法,是进行数据的初始化。

        /**
         * 数据的初始化
         */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);              
    
            INSTANCE = this;
            
            Constants.initializeConstantsFromResources(this);
            
            Controller.getInstance().setPreferences(PreferenceManager.getDefaultSharedPreferences(this));       
            
            if (Controller.getInstance().getPreferences().getBoolean(Constants.PREFERENCES_SHOW_FULL_SCREEN, false)) {            
                getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
            }
            
            if (Controller.getInstance().getPreferences().getBoolean(Constants.PREFERENCES_GENERAL_HIDE_TITLE_BARS, true)) {
                requestWindowFeature(Window.FEATURE_NO_TITLE);
            }
    
            setProgressBarVisibility(true);
            
            setContentView(R.layout.main);                        
            
            mCircularProgress = getResources().getDrawable(R.drawable.spinner);
            
            EventController.getInstance().addDownloadListener(this);                
                    
            mHideToolbarsRunnable = null;
            
            mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            
            buildComponents();                
            
            mViewFlipper.removeAllViews();   
            
            updateSwitchTabsMethod();
            updateBookmarksDatabaseSource();
            
            registerPreferenceChangeListener();
            
            Intent i = getIntent();
            if (i.getData() != null) {
                // App first launch from another app.
                addTab(false);
                navigateToUrl(i.getDataString());
            } else {
                // Normal start.
                int currentVersionCode = ApplicationUtils.getApplicationVersionCode(this);
                int savedVersionCode = PreferenceManager.getDefaultSharedPreferences(this).getInt(Constants.PREFERENCES_LAST_VERSION_CODE, -1);
                
                // If currentVersionCode and savedVersionCode are different, the application has been updated.
                if (currentVersionCode != savedVersionCode) {
                    // Save current version code.
                    Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
                    editor.putInt(Constants.PREFERENCES_LAST_VERSION_CODE, currentVersionCode);
                    editor.commit();
                    
                    // Display changelog dialog.
                    Intent changelogIntent = new Intent(this, ChangelogActivity.class);
                    startActivity(changelogIntent);
                }
                
                boolean lastPageRestored = false;
                if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Constants.PREFERENCES_BROWSER_RESTORE_LAST_PAGE, false)) {
                    if (savedInstanceState != null) {                
                        String savedUrl = savedInstanceState.getString(Constants.EXTRA_SAVED_URL);
                        if (savedUrl != null) {
                            addTab(false);
                            navigateToUrl(savedUrl);
                            lastPageRestored = true;
                        }
                    }
                }
                
                if (!lastPageRestored) {
                    addTab(true);
                }
            }
            
            initializeWebIconDatabase();
            
            startToolbarsHideRunnable();
            
        }

    从上述的源代码,我们可以清楚看出啦:

    ①,相应的初始化的内容,是从sharedprefrence这个xml文件中读取相应是否全屏啊,是否有标题这些所谓变量,来决定他显示显示相应的内容。

    ②,在这里进行相应数据化的初始化。

    ③,找到相应的控件。

    ④,未控件赋予相应事件的监听。

    ⑤,导航到相应的界面

    接下来的源代码了,主要是解决退出销毁数据,保存数据的方法,开启新意图的方法。

        /**
         * 销毁界面
         */
        @Override
        protected void onDestroy() {
            WebIconDatabase.getInstance().close();
            
            if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Constants.PREFERENCES_PRIVACY_CLEAR_CACHE_ON_EXIT, false)) {
                mCurrentWebView.clearCache(true);
            }
            
            EventController.getInstance().removeDownloadListener(this);
            
            PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(mPreferenceChangeListener);
    
            super.onDestroy();
        }
    
        /**
         * 保存相应的数据
         */
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            outState.putString(Constants.EXTRA_SAVED_URL, mCurrentWebView.getUrl());
            super.onSaveInstanceState(outState);
        }
    
        /**
         * Handle url request from external apps.
         * @param intent The intent.
         */
        @Override
        protected void onNewIntent(Intent intent) {
            if (intent.getData() != null) {
                addTab(false);
                navigateToUrl(intent.getDataString());
            }
            
            setIntent(intent);
            
            super.onNewIntent(intent);
        }        
        

    我们得出来这样的结论了,功能有三

    ①保存数据,将相应的URL数据保存起来。

    ②退出时候,判断这个是否需要清空相应的缓存,将相应的sharedpreference的监听者移除。

    ③开启新的一个意图的时候,导航到相应URL的页面,开始新的意图。

    在上面oncreate的方法中,我们说到了他有初始化控件的方法,那长成了什么样子了,我们来瞧一瞧:

        /**
         * Create main UI.
         */
        private void buildComponents() {
            
            mToolsActionGrid = new QuickActionGrid(this);
            mToolsActionGrid.addQuickAction(new QuickAction(this, R.drawable.ic_btn_home, R.string.QuickAction_Home));
            mToolsActionGrid.addQuickAction(new QuickAction(this, R.drawable.ic_btn_share, R.string.QuickAction_Share));
            mToolsActionGrid.addQuickAction(new QuickAction(this, R.drawable.ic_btn_find, R.string.QuickAction_Find));
            mToolsActionGrid.addQuickAction(new QuickAction(this, R.drawable.ic_btn_select, R.string.QuickAction_SelectText));
            mToolsActionGrid.addQuickAction(new QuickAction(this, R.drawable.ic_btn_mobile_view, R.string.QuickAction_MobileView));
                    
            mToolsActionGrid.setOnQuickActionClickListener(new OnQuickActionClickListener() {            
                @Override
                public void onQuickActionClicked(QuickActionWidget widget, int position) {
                    switch (position) {
                    case 0:
                        navigateToHome();
                        break;
                    case 1:
                        ApplicationUtils.sharePage(MainActivity.this, mCurrentWebView.getTitle(), mCurrentWebView.getUrl());
                        break;
                    case 2:                    
                        // Somewhat dirty hack: when the find dialog was shown from a QuickAction,
                        // the soft keyboard did not show... Hack is to wait a little before showing
                        // the file dialog through a thread.
                        startShowFindDialogRunnable();
                        break;
                    case 3:
                        swithToSelectAndCopyTextMode();
                        break;
                    case 4:
                        String currentUrl = mUrlEditText.getText().toString();
                        
                        // Do not reload mobile view if already on it.
                        if (!currentUrl.startsWith(Constants.URL_GOOGLE_MOBILE_VIEW_NO_FORMAT)) {
                            String url = String.format(Constants.URL_GOOGLE_MOBILE_VIEW, mUrlEditText.getText().toString());
                            navigateToUrl(url);
                        }
                        break;                
                    }
                }
            });
                    
            mToolsActionGrid.setOnDismissListener(new PopupWindow.OnDismissListener() {            
                @Override
                public void onDismiss() {
                    mToolsActionGridVisible = false;
                    startToolbarsHideRunnable();
                }
            });
            
            mGestureDetector = new GestureDetector(this, new GestureListener());
            
            mUrlBarVisible = true;
            
            mWebViews = new ArrayList<CustomWebView>();
            Controller.getInstance().setWebViewList(mWebViews);
            
            mBubbleRightView = (ImageView) findViewById(R.id.BubbleRightView);
            mBubbleRightView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    setToolbarsVisibility(true);                
                }
            });        
            mBubbleRightView.setVisibility(View.GONE);
            
            mBubbleLeftView = (ImageView) findViewById(R.id.BubbleLeftView);
            mBubbleLeftView.setOnClickListener(new View.OnClickListener() {            
                @Override
                public void onClick(View v) {
                    setToolbarsVisibility(true);
                }
            });
            mBubbleLeftView.setVisibility(View.GONE);
            
            mViewFlipper = (ViewFlipper) findViewById(R.id.ViewFlipper);
            
            mTopBar = (LinearLayout) findViewById(R.id.BarLayout);        
            mTopBar.setOnClickListener(new OnClickListener() {            
                @Override
                public void onClick(View v) {
                    // Dummy event to steel it from the WebView, in case of clicking between the buttons.                
                }
            });
            
            mBottomBar = (LinearLayout) findViewById(R.id.BottomBarLayout);        
            mBottomBar.setOnClickListener(new OnClickListener() {            
                @Override
                public void onClick(View v) {
                    // Dummy event to steel it from the WebView, in case of clicking between the buttons.                
                }
            });
            
            mFindBar = (LinearLayout) findViewById(R.id.findControls);
            mFindBar.setVisibility(View.GONE);
            
            mPreviousTabView = (ImageView) findViewById(R.id.PreviousTabView);
            mPreviousTabView.setOnClickListener(new View.OnClickListener() {            
                @Override
                public void onClick(View v) {
                    showPreviousTab(true);
                }
            });
            mPreviousTabView.setVisibility(View.GONE);
            
            mNextTabView = (ImageView) findViewById(R.id.NextTabView);
            mNextTabView.setOnClickListener(new View.OnClickListener() {            
                @Override
                public void onClick(View v) {
                    showNextTab(true);
                }
            });
            mNextTabView.setVisibility(View.GONE);
            
            String[] from = new String[] {UrlSuggestionCursorAdapter.URL_SUGGESTION_TITLE, UrlSuggestionCursorAdapter.URL_SUGGESTION_URL};
            int[] to = new int[] {R.id.AutocompleteTitle, R.id.AutocompleteUrl};
            
            UrlSuggestionCursorAdapter adapter = new UrlSuggestionCursorAdapter(this, R.layout.url_autocomplete_line, null, from, to);
                      
            adapter.setCursorToStringConverter(new CursorToStringConverter() {            
                @Override
                public CharSequence convertToString(Cursor cursor) {
                    String aColumnString = cursor.getString(cursor.getColumnIndex(UrlSuggestionCursorAdapter.URL_SUGGESTION_URL));
                    return aColumnString;
                }
            });
            
            adapter.setFilterQueryProvider(new FilterQueryProvider() {        
                @Override
                public Cursor runQuery(CharSequence constraint) {
                    if ((constraint != null) &&
                            (constraint.length() > 0)) {
                        return BookmarksProviderWrapper.getUrlSuggestions(getContentResolver(),
                                constraint.toString(),
                                PreferenceManager.getDefaultSharedPreferences(MainActivity.this).getBoolean(Constants.PREFERENCE_USE_WEAVE, false));
                    } else {
                        return BookmarksProviderWrapper.getUrlSuggestions(getContentResolver(),
                                null,
                                PreferenceManager.getDefaultSharedPreferences(MainActivity.this).getBoolean(Constants.PREFERENCE_USE_WEAVE, false));
                    }
                }
            });
            
            mUrlEditText = (AutoCompleteTextView) findViewById(R.id.UrlText);
            mUrlEditText.setThreshold(1);
            mUrlEditText.setAdapter(adapter);        
            
            mUrlEditText.setOnKeyListener(new View.OnKeyListener() {
    
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {                                                
                    if (keyCode == KeyEvent.KEYCODE_ENTER) {
                        navigateToUrl();
                        return true;
                    }
                    
                    return false;
                }
                
            });
            
    
            mUrlTextWatcher = new TextWatcher() {            
                @Override
                public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { }
    
                @Override
                public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { }
    
                @Override
                public void afterTextChanged(Editable arg0) {
                    updateGoButton();
                }
            };
            
            mUrlEditText.addTextChangedListener(mUrlTextWatcher);
            
            mUrlEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    // Select all when focus gained.
                    if (hasFocus) {
                        mUrlEditText.setSelection(0, mUrlEditText.getText().length());
                    }
                }
            });        
            
            mUrlEditText.setCompoundDrawablePadding(5);
                    
            mGoButton = (ImageButton) findViewById(R.id.GoBtn);        
            mGoButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    
                    if (mCurrentWebView.isLoading()) {
                        mCurrentWebView.stopLoading();
                    } else if (!mCurrentWebView.isSameUrl(mUrlEditText.getText().toString())) {
                        navigateToUrl();
                    } else {
                        mCurrentWebView.reload();
                    }
                }          
            });
            
            mToolsButton = (ImageButton) findViewById(R.id.ToolsBtn);
            mToolsButton.setOnClickListener(new View.OnClickListener() {            
                @Override
                public void onClick(View v) {
                    mToolsActionGridVisible = true;
                    mToolsActionGrid.show(v);                
                }
            });
            
            mProgressBar = (ProgressBar) findViewById(R.id.WebViewProgress);
            mProgressBar.setMax(100);
            
            mPreviousButton = (ImageButton) findViewById(R.id.PreviousBtn);
            mNextButton = (ImageButton) findViewById(R.id.NextBtn);
            
            mPreviousButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    navigatePrevious();
                }          
            });
            
            mNextButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    navigateNext();
                }          
            });
            
            mNewTabButton = (ImageButton) findViewById(R.id.NewTabBtn);
            mNewTabButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    addTab(true);
                }          
            });
            
            mRemoveTabButton = (ImageButton) findViewById(R.id.RemoveTabBtn);
            mRemoveTabButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    if (mViewFlipper.getChildCount() == 1 && !mCurrentWebView.getUrl().equals(Constants.URL_ABOUT_START)) {
                        navigateToHome();
                        updateUI();
                        updatePreviousNextTabViewsVisibility();
                    }
                    else
                        removeCurrentTab();
                }          
            });
            
            mQuickButton = (ImageButton) findViewById(R.id.QuickBtn);
            mQuickButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {                
                    onQuickButton();
                }          
            });
            
            mFindPreviousButton = (ImageButton) findViewById(R.id.find_previous);
            mFindPreviousButton.setOnClickListener(new OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    mCurrentWebView.findNext(false);
                    hideKeyboardFromFindDialog();
                }
            });
            
            mFindNextButton = (ImageButton) findViewById(R.id.find_next);
            mFindNextButton.setOnClickListener(new OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    mCurrentWebView.findNext(true);
                    hideKeyboardFromFindDialog();
                }
            });
            
            mFindCloseButton = (ImageButton) findViewById(R.id.find_close);
            mFindCloseButton.setOnClickListener(new OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    closeFindDialog();
                }
            });
            
            mFindText = (EditText) findViewById(R.id.find_value);
            mFindText.addTextChangedListener(new TextWatcher() {
                
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    doFind();
                }
                
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
                
                @Override
                public void afterTextChanged(Editable s) { }
            });
    
        }

    由这一大堆源代码,我们可以总结出这样的功能特点:

    ①我们为了满足自己的代码的需求初始化了QuickActionGrid这个控件,这个控件添加了主页,标签,添加标签功能到这个控件中。

    ②为了QuickActionGrid这个控件,赋予相应的事件,不同的事件做不同的动作。

    ③监听了相应动作手势的变化。

    ④找到相应的按钮控件,赋予相应的按钮控件的点击事件。

    ⑤实例化相应progressbar,使他的最大值是100.

    ⑥找到相应的匹配的文本框,从而为其监听文本变化的事件,从而完全实现匹配的效果。

    ⑦声明一个adapter,把相应数据填充出来。

    这个重头戏介绍完成以后,我们在看看sharedpreference中处理方法,这些处理方法,主要是处理一些配置类的信息。

    /**
         * 注册一个preference的监听者
         */
        private void registerPreferenceChangeListener() {
            mPreferenceChangeListener = new OnSharedPreferenceChangeListener() {            
                @Override
                public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
                    if (key.equals(Constants.PREFERENCE_BOOKMARKS_DATABASE)) {
                        updateBookmarksDatabaseSource();
                    }
                }
            };
            
            PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(mPreferenceChangeListener);
        }
        
        /**
         * Apply preferences to the current UI objects.
         */
        public void applyPreferences() {        
            // To update to Bubble position.
            setToolbarsVisibility(false);
            
            updateSwitchTabsMethod();
            
            for (CustomWebView view : mWebViews) {
                view.initializeOptions();
            }
        }

    这段代码给予我们起始有这么几点:

    ①读取相应的数据库配置信息,更新标签的数据源。为相应的数据类注册一个监听者。

    ②为相应ui 对象赋值一些数据信息。

    浏览器中webview是一个浏览器重中之重,我们在下面篇幅中,主要来自己初始化一个webview,源代码如下:

        /**
         * Initialize a newly created WebView.
         */
        private void initializeCurrentWebView() {
            
            mCurrentWebView.setWebViewClient(new CustomWebViewClient(this));
            mCurrentWebView.setOnTouchListener(this);
            
            mCurrentWebView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
    
                @Override
                public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
                    HitTestResult result = ((WebView) v).getHitTestResult();
                    
                    int resultType = result.getType();
                    if ((resultType == HitTestResult.ANCHOR_TYPE) ||
                            (resultType == HitTestResult.IMAGE_ANCHOR_TYPE) ||
                            (resultType == HitTestResult.SRC_ANCHOR_TYPE) ||
                            (resultType == HitTestResult.SRC_IMAGE_ANCHOR_TYPE)) {
                        
                        Intent i = new Intent();
                        i.putExtra(Constants.EXTRA_ID_URL, result.getExtra());
                        
                        MenuItem item = menu.add(0, CONTEXT_MENU_OPEN, 0, R.string.Main_MenuOpen);
                        item.setIntent(i);
        
                        item = menu.add(0, CONTEXT_MENU_OPEN_IN_NEW_TAB, 0, R.string.Main_MenuOpenNewTab);                    
                        item.setIntent(i);
                        
                        item = menu.add(0, CONTEXT_MENU_COPY, 0, R.string.Main_MenuCopyLinkUrl);                    
                        item.setIntent(i);
                        
                        item = menu.add(0, CONTEXT_MENU_DOWNLOAD, 0, R.string.Main_MenuDownload);                    
                        item.setIntent(i);
                        
                        item = menu.add(0, CONTEXT_MENU_SHARE, 0, R.string.Main_MenuShareLinkUrl);                    
                        item.setIntent(i);
                    
                        menu.setHeaderTitle(result.getExtra());                    
                    } else if (resultType == HitTestResult.IMAGE_TYPE) {
                        Intent i = new Intent();
                        i.putExtra(Constants.EXTRA_ID_URL, result.getExtra());
                        
                        MenuItem item = menu.add(0, CONTEXT_MENU_OPEN, 0, R.string.Main_MenuViewImage);                    
                        item.setIntent(i);
                        
                        item = menu.add(0, CONTEXT_MENU_COPY, 0, R.string.Main_MenuCopyImageUrl);                    
                        item.setIntent(i);
                        
                        item = menu.add(0, CONTEXT_MENU_DOWNLOAD, 0, R.string.Main_MenuDownloadImage);                    
                        item.setIntent(i);    
                        
                        item = menu.add(0, CONTEXT_MENU_SHARE, 0, R.string.Main_MenuShareImageUrl);                    
                        item.setIntent(i);
                        
                        menu.setHeaderTitle(result.getExtra());
                        
                    } else if (resultType == HitTestResult.EMAIL_TYPE) {
                        
                        Intent sendMail = new Intent(Intent.ACTION_VIEW, Uri.parse(WebView.SCHEME_MAILTO + result.getExtra()));
                        
                        MenuItem item = menu.add(0, CONTEXT_MENU_SEND_MAIL, 0, R.string.Main_MenuSendEmail);                    
                        item.setIntent(sendMail);                                        
                        
                        Intent i = new Intent();
                        i.putExtra(Constants.EXTRA_ID_URL, result.getExtra());
                        
                        item = menu.add(0, CONTEXT_MENU_COPY, 0, R.string.Main_MenuCopyEmailUrl);                    
                        item.setIntent(i);        
                        
                        item = menu.add(0, CONTEXT_MENU_SHARE, 0, R.string.Main_MenuShareEmailUrl);                    
                        item.setIntent(i);
                        
                        menu.setHeaderTitle(result.getExtra());
                    }
                }
                
            });      
            
            mCurrentWebView.setDownloadListener(new DownloadListener() {
    
                @Override
                public void onDownloadStart(String url, String userAgent,
                        String contentDisposition, String mimetype,
                        long contentLength) {
                    doDownloadStart(url, userAgent, contentDisposition, mimetype, contentLength);
                }
                
            });
            
            final Activity activity = this;
            mCurrentWebView.setWebChromeClient(new WebChromeClient() {
                
                @SuppressWarnings("unused")
                // This is an undocumented method, it _is_ used, whatever Eclipse may think :)
                // Used to show a file chooser dialog.
                public void openFileChooser(ValueCallback<Uri> uploadMsg) {
                    mUploadMessage = uploadMsg;
                    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                    i.addCategory(Intent.CATEGORY_OPENABLE);
                    i.setType("*/*");
                    MainActivity.this.startActivityForResult(
                            Intent.createChooser(i, MainActivity.this.getString(R.string.Main_FileChooserPrompt)),
                            OPEN_FILE_CHOOSER_ACTIVITY);
                }
                
                @Override
                public Bitmap getDefaultVideoPoster() {
                    if (mDefaultVideoPoster == null) {
                        mDefaultVideoPoster = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.default_video_poster);
                    }
                    
                    return mDefaultVideoPoster;
                }
    
                @Override
                public View getVideoLoadingProgressView() {
                    if (mVideoProgressView == null) {
                        LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
                        mVideoProgressView = inflater.inflate(R.layout.video_loading_progress, null);
                    }
                    
                    return mVideoProgressView;
                }
                
                public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
                    showCustomView(view, callback);
                }
                
                @Override
                public void onHideCustomView() {
                    hideCustomView();
                }
                
    //            @Override
    //            public void onShowCustomView(View view, CustomViewCallback callback) {
    //                super.onShowCustomView(view, callback);
    //                
    //                if (view instanceof FrameLayout) {
    //                    mCustomViewContainer = (FrameLayout) view;
    //                    mCustomViewCallback = callback;
    //                    
    //                    mContentView = (LinearLayout) findViewById(R.id.MainContainer);
    //                    
    //                    if (mCustomViewContainer.getFocusedChild() instanceof VideoView) {
    //                        mCustomVideoView = (VideoView) mCustomViewContainer.getFocusedChild();
    //                        // frame.removeView(video);
    //                        mContentView.setVisibility(View.GONE);
    //                        mCustomViewContainer.setVisibility(View.VISIBLE);
    //                        
    //                        setContentView(mCustomViewContainer);
    //                        //mCustomViewContainer.bringToFront();
    //
    //                        mCustomVideoView.setOnCompletionListener(new OnCompletionListener() {                            
    //                            @Override
    //                            public void onCompletion(MediaPlayer mp) {
    //                                mp.stop();
    //                                onHideCustomView();
    //                            }
    //                        });
    //                        
    //                        mCustomVideoView.setOnErrorListener(new OnErrorListener() {                        
    //                            @Override
    //                            public boolean onError(MediaPlayer mp, int what, int extra) {
    //                                onHideCustomView();
    //                                return true;
    //                            }
    //                        });
    //                        
    //                        mCustomVideoView.start();
    //                    }
    //
    //                }
    //            }
    //
    //            @Override
    //            public void onHideCustomView() {
    //                super.onHideCustomView();
    //                
    //                if (mCustomVideoView == null) {
    //                    return;
    //                }
    //                
    //                mCustomVideoView.setVisibility(View.GONE);
    //                mCustomViewContainer.removeView(mCustomVideoView);
    //                mCustomVideoView = null;
    //                
    //                mCustomViewContainer.setVisibility(View.GONE);
    //                mCustomViewCallback.onCustomViewHidden();
    //                
    //                mContentView.setVisibility(View.VISIBLE);
    //                setContentView(mContentView);                
    //            }
    
                @Override
                public void onProgressChanged(WebView view, int newProgress) {
                    ((CustomWebView) view).setProgress(newProgress);                
                    mProgressBar.setProgress(mCurrentWebView.getProgress());
                }
                            
                @Override
                public void onReceivedIcon(WebView view, Bitmap icon) {
                    new Thread(new FaviconUpdaterRunnable(MainActivity.this, view.getUrl(), view.getOriginalUrl(), icon)).start();
                    updateFavIcon();
                    
                    super.onReceivedIcon(view, icon);
                }
    
                @Override
                public boolean onCreateWindow(WebView view, final boolean dialog, final boolean userGesture, final Message resultMsg) {
                    
                    WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
                    
                    addTab(false, mViewFlipper.getDisplayedChild());
                    
                    transport.setWebView(mCurrentWebView);
                    resultMsg.sendToTarget();
                    
                    return true;
                }
                
                @Override
                public void onReceivedTitle(WebView view, String title) {
                    setTitle(String.format(getResources().getString(R.string.ApplicationNameUrl), title)); 
                    
                    startHistoryUpdaterRunnable(title, mCurrentWebView.getUrl(), mCurrentWebView.getOriginalUrl());
                    
                    super.onReceivedTitle(view, title);
                }
    
                @Override
                public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
                    new AlertDialog.Builder(activity)
                    .setTitle(R.string.Commons_JavaScriptDialog)
                    .setMessage(message)
                    .setPositiveButton(android.R.string.ok,
                            new AlertDialog.OnClickListener()
                    {
                        public void onClick(DialogInterface dialog, int which) {
                            result.confirm();
                        }
                    })
                    .setCancelable(false)
                    .create()
                    .show();
    
                    return true;
                }
    
                @Override
                public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
                    new AlertDialog.Builder(MainActivity.this)
                    .setTitle(R.string.Commons_JavaScriptDialog)
                    .setMessage(message)
                    .setPositiveButton(android.R.string.ok, 
                            new DialogInterface.OnClickListener() 
                    {
                        public void onClick(DialogInterface dialog, int which) {
                            result.confirm();
                        }
                    })
                    .setNegativeButton(android.R.string.cancel, 
                            new DialogInterface.OnClickListener() 
                    {
                        public void onClick(DialogInterface dialog, int which) {
                            result.cancel();
                        }
                    })
                    .create()
                    .show();
    
                    return true;
                }
    
                @Override
                public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {
                    
                    final LayoutInflater factory = LayoutInflater.from(MainActivity.this);
                    final View v = factory.inflate(R.layout.javascript_prompt_dialog, null);
                    ((TextView) v.findViewById(R.id.JavaScriptPromptMessage)).setText(message);
                    ((EditText) v.findViewById(R.id.JavaScriptPromptInput)).setText(defaultValue);
    
                    new AlertDialog.Builder(MainActivity.this)
                        .setTitle(R.string.Commons_JavaScriptDialog)
                        .setView(v)
                        .setPositiveButton(android.R.string.ok,
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int whichButton) {
                                        String value = ((EditText) v.findViewById(R.id.JavaScriptPromptInput)).getText()
                                                .toString();
                                        result.confirm(value);
                                    }
                                })
                        .setNegativeButton(android.R.string.cancel,
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int whichButton) {
                                        result.cancel();
                                    }
                                })
                        .setOnCancelListener(
                                new DialogInterface.OnCancelListener() {
                                    public void onCancel(DialogInterface dialog) {
                                        result.cancel();
                                    }
                                })
                        .show();
                    
                    return true;
    
                }        
                
            });
        }

    对于这个方法,我们需要对其进行讨论,

    ①他需要对其相应按键做出正常的处理,判断他是按键不同,进行不同操作。

    ②对其相应的下载的接口进行了监听,进行webclient下载的处理。

    ③对其文件上传,作起处理,跳转到文件上传的页面。

    ④对其view进行了处理,使其相应progress的view文件进行填充。

    ⑤创建一个窗体,使其显示是该指定的webview。

    ⑥对弹出来js源代码进行处理,使其页面上的js代码在webview能够正常的显示。

    在该浏览器中添加相应的tab页,是一个重要的功能,因此我们分析分析,源代码如下:

        /**
         * Add a new tab.
         * @param navigateToHome If True, will load the user home page.
         * @param parentIndex The index of the new tab.
         */
        private void addTab(boolean navigateToHome, int parentIndex) {
            if (mFindDialogVisible) {
                closeFindDialog();
            }
            
            RelativeLayout view = (RelativeLayout) mInflater.inflate(R.layout.webview, mViewFlipper, false);
            
            mCurrentWebView = (CustomWebView) view.findViewById(R.id.webview);
            
            initializeCurrentWebView();                
            
            synchronized (mViewFlipper) {
                if (parentIndex != -1) {
                    mWebViews.add(parentIndex + 1, mCurrentWebView);            
                    mViewFlipper.addView(view, parentIndex + 1);
                } else {
                    mWebViews.add(mCurrentWebView);
                    mViewFlipper.addView(view);
                }
                mViewFlipper.setDisplayedChild(mViewFlipper.indexOfChild(view));            
            }
            
            updateUI();
            updatePreviousNextTabViewsVisibility();
            
            mUrlEditText.clearFocus();
            
            if (navigateToHome) {
                navigateToHome();
            }
        }
        
        /**
         * Remove the current tab.
         */
        private void removeCurrentTab() {
            
            if (mFindDialogVisible) {
                closeFindDialog();
            }
            
            int removeIndex = mViewFlipper.getDisplayedChild();
            
            mCurrentWebView.doOnPause();
            
            synchronized (mViewFlipper) {
                mViewFlipper.removeViewAt(removeIndex);
                mViewFlipper.setDisplayedChild(removeIndex - 1);            
                mWebViews.remove(removeIndex);            
            }
            
            mCurrentWebView = mWebViews.get(mViewFlipper.getDisplayedChild());
            
            updateUI();
            updatePreviousNextTabViewsVisibility();
            
            mUrlEditText.clearFocus();
        }

    我们首先

    ①找到相应的viewflipper控件,在viewflipper中,显示到该初始化webview。并且对其计数器加一,当前文本框失去焦点。

    ②移去view的时候,在webview移去,计数器减一,界面更新,文本框失去焦点。

    有了这些主要的方法做支持,一个webview就这样显示出来,下节主要讲①一个网页显示在webview控件中,②如何正常隐藏显示标题栏。③如何用runnable来更加快速的显示网页,不使其页面实现卡顿。

  • 相关阅读:
    Office办公软件停止工作解决方案
    Jquery blockUI用法
    IE浏览器对js代码的高要求
    IIS中应用程序切换物理路径遇到的问题
    using关键字
    剑指offer-面试题23-链表中环的入口节点-双指针
    剑指offer-面试题22-链表中倒数第k个节点-双指针
    剑指offer-面试题21-调整数组顺序使奇数位于偶数前面-双指针
    剑指offer-面试题20-表示数值的字符串-字符串
    剑指offer-面试题19-正则表达式匹配-字符串
  • 原文地址:https://www.cnblogs.com/manuosex/p/3612177.html
Copyright © 2011-2022 走看看