揭祕uc瀏覽器一

首先,看一下項目完成後的,最終效果是這樣的:javascript

一.主界面java

二,書籤界面android

3、主界面web

四.操做對話框界面數據庫

這幾個界面你是否看到了uc瀏覽器的影子了,其實我說你也能夠了,在接下來篇幅中,我將手把手叫你們完成這個瀏覽器。瀏覽器

首先,咱們從主界面開始吧,這是一個主線,項目的一些開始由他開始了。緩存

 從圖一中,咱們能夠看出其佈局文件主要的佈局文件以線性佈局爲主,而同時了他嵌套了相對佈局,有圖有真相,下圖就是我對主頁佈局文件一種說明:多線程

從上圖的佈局文件,咱們能夠清晰的看出來了,中間viewflipper這個翻頁控件有大做用的,裏面的一些網頁內容將展示如此。app

android佈局文件當然重要,但只有了代碼控制,才能使一個app變得"有血有肉",咱們來看看這個主頁面的控制文件。ide

照例了,咱們先介紹了一些常量的聲明:這些在下面的代碼中將會大量的使用,源代碼以下:

//滑動像素的入口常量
    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來更加快速的顯示網頁,不使其頁面實現卡頓。

相關文章
相關標籤/搜索