在做小帮手1.2的过程中,添加大声Hi的webView的时候的一些知识:
1.webView的两个client
WebViewClient:WebViewClient会在一些影响网页内容的动作发生时被调用,比如url的打开
WebChromeClient:WebChromeClient会在一些影响浏览器ui交互动作发生时被调用,
与界面有关的一切事情都是在调用它,比如js确认框和警告框、js加载前、js操作超时、webView获得焦点等等
2.WebSettings
顾名思义,是指关于WebView的所有配置,比如:文件操作、页面大小缩放,是否允许js脚本运行、
是否允许图片自动加载、是否允许数据及密码保存等等
3.WebView中的JS交互
现在大多数应用都是采用的hybrid,也就是原生界面和H5的融合,典型的例子就是手机淘宝,QQ,在华中大的APP里面
也发现了hybrid
在WebView中,要实现JS交互首先得setJavaScriptEnabled为true,然后得到websettings的对象,调用addJavascriptInterface方法,将java对象绑定到webView中,
以方便从页面js中控制java对象,实现用本地java代码和html页面进行交互
4.当前网页的链接仍在webView中跳转
1 @Override 2 public boolean shouldOverrideUrlLoading(WebView view, String url) { 3 view.loadUrl(url); 4 return true; 5 }
shouldOverrideUrlLoading表示当前webView中的一个新url需要加载时,给当前应用程序一个处理机会,如果没有重写此函数,webView请求ActivityManage选择合适的方式处理请求,
重写后return true表示让当前程序处理,return false表示让当前webView处理
5.网页自动化登陆
1 mWebView.setWebViewClient(new WebViewClient(){ 2 @Override 3 public void onPageFinished(WebView view, String url) {//页面加载完成后实现自动登陆 4 account = ((RedActivity) activity).getRedApplication().getMainAccount(); 5 try{ 6 stu = account.getStuNum(); 7 id = account.getIdNum(); 8 requestUrl = "javascript:document.getElementsByName('username')[0].value='"+stu+"';javascript:document.getElementsByName('password')[0].value='"+id+"';javascript:document.getElementById('login').click()"; 9 if(i<2){ 10 mWebView.loadUrl(requestUrl); 11 }else{ 12 return; 13 }//居然会无限循坏加载 14 }catch(NullPointerException e){ 15 Util.Toast(getApplicationContext(), "不好意思(-。-;),出了点错误,只能手动登陆了"); 16 }//如果发生了空指针了 17 //居然会无限循坏加载*/ 18 i++; 19 /*mWebView.loadUrl("javascript:document.getElementsByName('password')[0].value='161339'"); 20 mWebView.loadUrl("javascript:document.getElementById('login').click()");*/ 21 } 22 }
通过Override onPageFinished方法,调用网页中的JS函数来实现,其中我遇到了无限循环加载的bug,一直跳登陆成功的网页,
发现是一直在调用onPageFinished方法,所以就给了个i,来判断,让下次不再调用
6.关于JS暴露
小帮手2.0中
1.Material Design中左上角的箭头旋转效果的实现
首先看了一下github上面实现这个效果的源码
Material Design中不再提倡使用ActionBar,而是出现了一个更好的东西:APP Bar,其实APP Bar就是V7-21包中的Tool Bar,
首先要实现Tool Bar替代ActionBar,要将Theme继承Theme.AppCompat.NoActionBar.因为要替换掉ActionBar,所以得选择这种Theme来继承
ToolBar其实就是android.support.v7.widget.Toolbar中的一个widget
下面是实现代码:
private static DrawerLayout mDrawerLayout; private ActionBarDrawerToggle mDrawerToggle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); configureToolbar(); configureDrawer(); } private void configureToolbar() { Toolbar mainToolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(mainToolbar); getSupportActionBar().setTitle(getString(R.string.tittle)); mainToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mDrawerLayout.isDrawerOpen(Gravity.START)) { mDrawerLayout.closeDrawer(Gravity.START); } else { mDrawerLayout.openDrawer(Gravity.START); } } }); } private void configureDrawer() { mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout, R.string.nav_drawer_open, R.string.nav_drawer_closed){ @Override public void onDrawerClosed(View view){ supportInvalidateOptionsMenu(); } @Override public void onDrawerOpened(View drawerView) { supportInvalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() } }; mDrawerLayout.setDrawerListener(mDrawerToggle); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); mDrawerToggle.syncState();//这个就应该是跟随手指滑动的状态来改变箭头的实时旋转 } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); }
XML:
1 <LinearLayout 2 xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:background="@android:color/white" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent"> 7 8 <android.support.v7.widget.Toolbar 9 android:id="@+id/toolbar" 10 android:layout_height="wrap_content" 11 android:layout_width="match_parent" 12 android:background="@color/theme_default_primary" 13 android:minHeight="?attr/actionBarSize"/> 14 15 <android.support.v4.widget.DrawerLayout 16 android:id="@+id/drawer_layout" 17 android:layout_width="match_parent" 18 android:layout_height="match_parent"> 19 20 <FrameLayout 21 android:id="@+id/tab_fragment" 22 android:layout_weight="2" 23 android:layout_width="match_parent" 24 android:layout_height="0px" /> 25 26 <FrameLayout 27 android:id="@+id/container" 28 android:layout_width="match_parent" 29 android:layout_height="match_parent" /> 30 31 <fragment 32 android:id="@+id/navigation_drawer" 33 android:layout_width="@dimen/navigation_drawer_width" 34 android:layout_height="match_parent" 35 android:layout_gravity="start" 36 android:name="com.mredrock.cyxbs.ui.activity.MainActivity$NavigationFragment"/> 37 </android.support.v4.widget.DrawerLayout> 38 </LinearLayout>
2.ListView的点击后保持选中的效果,网上的都好坑,尤其是实现初始化选中
第一种方法
1 listOptions.setOnItemClickListener(new AdapterView.OnItemClickListener() { 2 @Override 3 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 4 5 //make the place which be selected highlight 6 /*if(parent.getTag() != null){ 7 ((View)(parent).getTag()).setBackgroundDrawable(null); 8 } 9 (parent).setTag(view); 10 view.setBackgroundColor(Color.LTGRAY);*/ 11 } 12 })
通过使用TAG来实现,缺点就是不能实现初始化选中
第二种方法
在Adapter中的getView方法中:
if (position == selectedItem) { convertView.setBackgroundColor(Color.parseColor("#00BCD4")); }else{ convertView.setBackgroundColor(Color.TRANSPARENT); }
adapter中自定义一个方法:
1 public void setSelectItem(int selectedItem) { 2 this.selectedItem = selectedItem; 3 notifyDataSetChanged(); 4 }
然后在setOnItemClickListener中调用optionsAdapter.setSelectItem(position);