Android--Menus

简介:

前言

  本篇博客讲解一下菜单Menu的使用。菜单在windows应用中使用十分广泛,几乎所有的windows应用都有菜单,Android中也加入了菜单的支持。从官方文档了解到,从Android3.0(API level 11)开始,Android设备不再要求提供一个专门的菜单按钮,转而推荐使用ActionBar。所以现在市面上很多新设备使用三个虚拟按键,并不再额外提供菜单按钮,但是按钮的使用也是有些地方可以借鉴的。

  因为Android版本的发展,对于菜单的支持各个版本有很大的区别,而Android3.0是个分水岭,大概可以分为下面三类:

  • OptionMenu和ActionBar:一些操作的集合,如果开发的平台在Android3.0之上,推荐使用ActionBar,如果开发的平台在Android2.3或之下,还是可以使用OptionMenu的。
  • ContextMenu和ActionMode:ContextMenu是一个浮动的窗口形式展现一个选项列表,ActionMode是一个显示在屏幕顶部的操作栏,允许用户选择多个选项,ActionMode在Android3.0之后才有支持。
  • Pupop Menu:PopupMenu是固定在View上的模态菜单,以弹出的方式显示,在Android3.0之后才有支持。

  

在XML中定义一个菜单

  Android提供了标准的XML格式的资源文件来定义菜单项,并且对所有菜单类型都支持,推荐使用XML资源文件来定义菜单,之后再把它Inflater到Activity或者Fragment中,而不是在Activity中使用代码声明。

  而菜单的XML资源文件,需要创建在/res/menu/目录下,并且包含一下几个元素:

  • <menu>:定义一个Menu,是一个菜单资源文件的根节点,里面可以包含一个或者多个<item>和<group>元素。
  • <item>:创建一个MenuItem,代表了菜单中一个选项。
  • <group>:对菜单项进行分组,可以以组的形式操作菜单项。

  <item>元素除了常规的id、icon、title属性的支持,还有一个重要的属性:android:showAsAction,这个属性是起兼容性的,描述了在Android的高版本中,菜单项何时以何种方式加入到ActionBar中。

  <group>是对菜单进行分组,分组后的菜单显示效果并没有区别,唯一的区别在于可以针对菜单组进行操作,这样对于分类的菜单项,操作起来更方便,提供如下的操作:

  • Menu.setGroupCheckable():菜单组内的菜单是否都可选。
  • Menu.setGroupVisible():是否隐藏菜单组的所有菜单。
  • Menu.setGroupEnabled():菜单组的菜单是否有用。

  如果菜单项需要单选或者多选,可以使用android:checkableBehavior属性设置,它可以对单个<item>或者<group>设置一个组,这个属性接受三个参数:single,单选;all,多选,none,没有Checked的选项,默认。

  当创建好一个XML菜单资源文件之后,可以使用MenuInflater.inflate()方法填充菜单资源,使XML资源变成一个可编程的对象。

 

OptionMenu

  OptionMenu,选项菜单,必须设备具有菜单按钮才可以触发。因为屏幕的限制,最多只能展示六个菜单项,如果定义的菜单项超出了六个,其他的菜单项将被隐藏,第六个菜单将会显示“更多”,点击展开更多的菜单。虽说在Android3.0之后不再推荐使用选项菜单,但是如果使用了,在Android3.0之后的设备上,选项菜单项将被默认转移到ActionBar中,这个可以通过android:showAsAction属性控制。

  使用OptionMenu需要在Activity或者Fragment中重写onCreateOptionsMenu(Menu)方法,在这个方法中声明一个选项菜单。菜单的存在是为了提供操作,所以Activity和Fragment中还提供了一个onOptionsItemSelected(MenuItem)方法,用于响应选项菜单中选中的时候的响应。OptionMenu就是操作一个Menu对象和MenuItem对象。

  下面通过两个Demo来展示一段选项菜单的使用,分别使用代码声明菜单和XML资源文件声明菜单的方式说明。

  声明代码: 

复制代码
 1 package com.example.menudemo;
 2 
 3 import android.app.Activity;
 4 import android.content.Intent;
 5 import android.os.Bundle;
 6 import android.view.Menu;
 7 import android.view.MenuItem;
 8 import android.view.SubMenu;
 9 import android.widget.Toast;
10 
11 public class OptionMenu1Activitty extends Activity {
12 
13     @Override
14     protected void onCreate(Bundle savedInstanceState) {
15         // TODO Auto-generated method stub
16         super.onCreate(savedInstanceState);
17         setContentView(R.layout.activity_optionmenu1);
18     }
19 
20     @Override
21     public boolean onCreateOptionsMenu(Menu menu) {
22         
23         //直接Add菜单选项到Menu中
24         menu.add(1000, 100, 0, "System menu"); 
25         //获取添加的菜单选项,然后设置其图标
26         MenuItem menuItem2=menu.add(1000, 101, 1, "User menu"); 
27         menuItem2.setIcon(R.drawable.ic_launcher);
28         //获取添加的菜单选项,增加一个Intent,点击后转向IntentActivity
29         MenuItem menuItem3=menu.add(1000, 102, 2, "Intent menu"); 
30         menuItem3.setIcon(R.drawable.ic_launcher);
31         Intent intent=new Intent(OptionMenu1Activitty.this, IntentActivity.class);
32         menuItem3.setIntent(intent);        
33 
34         //添加一个SubMenu,点击后弹出一个子菜单对话框
35         SubMenu submenu=menu.addSubMenu(1000, 103, 3, "Sub menus");
36         submenu.add(1000, 104, 4, "Sub ment1");
37         submenu.add(1000, 105, 4, "Sub ment2");
38         submenu.add(1000, 106, 4, "Sub ment3");
39         return true;
40     }
41     
42     @Override
43     public boolean onOptionsItemSelected(MenuItem item) {
44         boolean flag;
45         switch (item.getItemId()) {
46         case 100:
47             Toast.makeText(OptionMenu1Activitty.this, "selected System menu", Toast.LENGTH_SHORT).show();
48             flag=true;
49             break;
50         case 101:
51             Toast.makeText(OptionMenu1Activitty.this, "selected User menu", Toast.LENGTH_SHORT).show();
52             flag=true;
53             break;
54         case 104:
55             Toast.makeText(OptionMenu1Activitty.this, "selected Sub menu1", Toast.LENGTH_SHORT).show();
56             flag=true;
57         default:
58             flag=super.onOptionsItemSelected(item);
59             break;
60         }
61         return flag;
62     }
63     
64 }
复制代码

 

  实现效果,Android2.3:

   使用XML资源文件定义选项菜单,XML资源文件:

复制代码
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <menu xmlns:android="http://schemas.android.com/apk/res/android" >
 3 
 4     <item
 5         android:id="@+id/item1"
 6         android:showAsAction="never"
 7         android:title="System menu">
 8     </item>
 9     <item
10         android:id="@+id/item2"
11         android:showAsAction="never"
12         android:title="User menu" 
13         android:icon="@drawable/ic_launcher">
14     </item>
15     <item
16         android:id="@+id/item3"
17         android:showAsAction="never"
18         android:title="Intent menu" 
19         android:icon="@drawable/ic_launcher">
20     </item>
21     <group android:id="@+id/group_file" >
22         <item android:id="@+id/menu_save" 
23               android:title="menu group save" />
24         <item android:id="@+id/menu_delete"
25               android:title="menu group delete" />
26     </group>
27     <item android:id="@+id/file"
28           android:title="Sub menus" >
29         <!-- "file" submenu -->
30         <menu>
31             <item android:id="@+id/sub_menu1"
32                   android:title="Sub menu1" />
33             <item android:id="@+id/sub_menu21"
34                   android:title="Sub menu2" />
35             <item android:id="@+id/sub_menu3"
36                   android:title="Sub menu3" />
37         </menu>
38     </item>
39 </menu>
复制代码

 Java代码:

复制代码
 1 package com.example.menudemo;
 2 
 3 import android.app.Activity;
 4 import android.content.Intent;
 5 import android.os.Bundle;
 6 import android.view.Menu;
 7 import android.view.MenuItem;
 8 import android.widget.TextView;
 9 import android.widget.Toast;
10 
11 public class OptionMenu2Activitty extends Activity {
12     private TextView  tv;
13     @Override
14     protected void onCreate(Bundle savedInstanceState) {
15         // TODO Auto-generated method stub
16         super.onCreate(savedInstanceState);
17         setContentView(R.layout.activity_optionmenu1);
18         tv=(TextView)findViewById(R.id.tvOptionMenu1);
19         tv.setText("加载XML资源填充Menu");        
20     }
21     
22     @Override
23     public boolean onCreateOptionsMenu(Menu menu) {
24         // 使用布局文件加载菜单
25         getMenuInflater().inflate(R.menu.optionmenu2, menu);
26         return super.onCreateOptionsMenu(menu);
27     }
28     
29     @Override
30     public boolean onOptionsItemSelected(MenuItem item) {
31 
32         switch (item.getItemId()) {
33         case R.id.item1:
34             Toast.makeText(OptionMenu2Activitty.this, "selected System menu", Toast.LENGTH_SHORT).show();
35             return true;
36         case R.id.item2:
37             Toast.makeText(OptionMenu2Activitty.this, "selected User menu", Toast.LENGTH_SHORT).show();
38             return true;
39         case R.id.item3:
40             Intent intent=new Intent(OptionMenu2Activitty.this, IntentActivity.class);
41             startActivity(intent);
42             return true;
43         case R.id.menu_save:
44             Toast.makeText(OptionMenu2Activitty.this, "file save", Toast.LENGTH_SHORT).show();
45             return true;
46         case R.id.sub_menu1:
47             Toast.makeText(OptionMenu2Activitty.this, "Selected sub_menu1", Toast.LENGTH_SHORT).show();
48             return true;
49         default:
50             return super.onOptionsItemSelected(item);
51         }
52         
53         
54     }
55     
56 }
复制代码

  效果和使用Java代码声明菜单一样,这里就不再展示了。

 

ContextMenu

  ContextMenu,上下文菜单提供了注册在View组件的菜单操作,它以一个浮动的窗口显示(类似于对话框),当用户长按某被注册了上下文菜单的视图,则触发上下文菜单显示。通常都用于ListView或者GridView等视图集合中。

  使用上下文菜单的步骤:

  1. 使用Activity.registerForContextMenu(View)方法为指定View注册上下文菜单。
  2. 在Activity或者Fragment中重写onCreateContextMenu()方法,当被注册的视图接受到长按事件后,系统调用onCreateContextMenu()方法,在这个方法中声明上下文菜单。
  3. 实现onContextItemSelected()方法,用于响应菜单想的选中。

  示例,菜单XML资源文件代码:

复制代码
 1 <menu xmlns:android="http://schemas.android.com/apk/res/android" >
 2 
 3      <item
 4         android:id="@+id/context_copy"
 5         android:orderInCategory="100"
 6         android:showAsAction="never"
 7         android:title="Copy"/>
 8     <item
 9         android:id="@+id/context_edit"
10         android:orderInCategory="100"
11         android:showAsAction="never"
12         android:title="Edit"/>
13     <item
14         android:id="@+id/context_delete"
15         android:orderInCategory="100"
16         android:showAsAction="never"
17         android:title="Delete"/>
18 </menu>
复制代码

  Java代码:

复制代码
 1 package com.example.menudemo;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import android.app.Activity;
 7 import android.os.Bundle;
 8 import android.view.ContextMenu;
 9 import android.view.MenuInflater;
10 import android.view.MenuItem;
11 import android.view.View;
12 import android.view.ContextMenu.ContextMenuInfo;
13 import android.widget.AdapterView.AdapterContextMenuInfo;
14 import android.widget.ArrayAdapter;
15 import android.widget.ListView;
16 import android.widget.Toast;
17 
18 public class ContextMenu1 extends Activity {
19     private ListView listview;
20     private List<String> dataList;
21     @Override
22     protected void onCreate(Bundle savedInstanceState) {
23         super.onCreate(savedInstanceState);
24         setContentView(R.layout.activity_contextmenu1);
25         listview=(ListView)findViewById(R.id.listView1);
26         dataList=getData();
27         ArrayAdapter<String> adapter=new  ArrayAdapter<String>(ContextMenu1.this,android.R.layout.simple_list_item_1, dataList);
28         listview.setAdapter(adapter);
29         //为ListView注册上下文菜单
30         registerForContextMenu(listview);
31     }
32     
33     @Override
34     public void onCreateContextMenu(ContextMenu menu, View v,
35             ContextMenuInfo menuInfo) {
36         super.onCreateContextMenu(menu, v, menuInfo);
37         //填充一个XML菜单文件
38         MenuInflater inflater = getMenuInflater();
39         inflater.inflate(R.menu.contextmenu, menu);
40     }
41     
42     @Override
43     public boolean onContextItemSelected(MenuItem item) {
44         //获取上下文菜单绑定的AdapterView的额外信息
45         AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
46         switch (item.getItemId()) {
47         case R.id.context_copy:
48             Toast.makeText(ContextMenu1.this, "copy "+dataList.get(info.position), Toast.LENGTH_SHORT).show();
49             return true;
50         case R.id.context_delete:
51             Toast.makeText(ContextMenu1.this, "delete "+dataList.get(info.position), Toast.LENGTH_SHORT).show();
52             return true;
53         case R.id.context_edit:
54             Toast.makeText(ContextMenu1.this, "edit " +dataList.get(info.position), Toast.LENGTH_SHORT).show();
55             return true;
56         default:
57             return super.onContextItemSelected(item);
58         }        
59     }
60     //ListView数据
61     public List<String> getData()
62     {        
63         List<String> data=new ArrayList<String>();
64         for(int i=0;i<8;i++)
65         {
66             data.add("item"+i);
67         }
68         return data;
69     }    
70 }
复制代码

  效果展示,Android4.0:

 

ActionMode

  ActionMode,是一个系统实现的用户交互,当用户使用ActionMode后,选择一个选项,一个上下文操作栏会出现在屏幕的顶端,呈现出用户可以对当前选中项目进行的操作选项。进入这种状态可以通过后退按钮或者调用finish()退出。ActionMode为Android3.0之后的支持,所以在开发3.0之后的应用,推荐使用ActionMode,而不是ContextMenu。

  使用ActionMode的步骤:

  1. 实现ActionMode.Callback接口。在它的回调方法中,可以设置操作的上下文操作栏。
  2. 在需要显示上下文操作栏的时候,调用startActionMode(ActionMode.Callback)。

  ActionMode.Callback是ActionMode定义的一个内部接口,这个接口需要实现下面四个方法:

  • boolean onCreateActionMode(ActionMode mode,Menu menu):第一次被创建的时候调用。
  • boolean onPrepareActionMode(ActionMode mode,Menu menu):刷新菜单列表的时候被调用,一般使用false即可。
  • boolean onActionItemClicked(ActionMode mode,MenuItem item):菜单项被选中的时候被调用。
  • void onDestroyActionMode(ActionMode mode):退出或销毁的时候被调用。

  示例:

复制代码
  1 package com.example.menudemo;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 
  6 import android.annotation.SuppressLint;
  7 import android.app.Activity;
  8 import android.os.Bundle;
  9 import android.view.ActionMode;
 10 import android.view.ActionMode.Callback;
 11 import android.view.Menu;
 12 import android.view.MenuInflater;
 13 import android.view.MenuItem;
 14 import android.view.View;
 15 import android.widget.AdapterView;
 16 import android.widget.AdapterView.AdapterContextMenuInfo;
 17 import android.widget.AdapterView.OnItemLongClickListener;
 18 import android.widget.ArrayAdapter;
 19 import android.widget.ListView;
 20 import android.widget.Toast;
 21 
 22 public class ActionModeMenu1 extends Activity {
 23     private ListView listview;
 24     private List<String> dataList;
 25     private ActionMode mActionMode;
 26     @Override
 27     protected void onCreate(Bundle savedInstanceState) {
 28         // TODO Auto-generated method stub
 29         super.onCreate(savedInstanceState);
 30         setContentView(R.layout.activity_contextmenu1);
 31         listview=(ListView)findViewById(R.id.listView1);
 32         dataList=getData();
 33         ArrayAdapter<String> adapter=new  ArrayAdapter<String>(ActionModeMenu1.this,android.R.layout.simple_list_item_1, dataList);
 34         listview.setAdapter(adapter);
 35         listview.setOnItemLongClickListener(new OnItemLongClickListener() {
 36             @SuppressLint("NewApi")
 37             @Override
 38             public boolean onItemLongClick(AdapterView<?> parent, View view,
 39                     int position, long id) {        
 40                 if (mActionMode != null) {
 41                     return false;
 42                 }
 43                 //显示ActionMode
 44                 mActionMode = startActionMode(mActionModeCallback);
 45                 //标记选中项的下表
 46                 mActionMode.setTag(position);
 47                 //标记ListView为可选状态
 48                 view.setSelected(true);
 49                 return true;
 50             }
 51         });
 52     }
 53     public List<String> getData()
 54     {
 55         List<String> data=new ArrayList<String>();
 56         for(int i=0;i<8;i++)
 57         {
 58             data.add("item"+i);
 59         }
 60         return data;
 61     }
 62     
 63     private ActionMode.Callback mActionModeCallback=new Callback() {
 64         
 65         @Override
 66         public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
 67             //刷新菜单列表的时候被调用,但是一般无需刷新
 68             return false;
 69         }
 70         
 71         @Override
 72         public void onDestroyActionMode(ActionMode mode) {
 73             //销毁ActionMode
 74             mActionMode = null;
 75         }
 76         
 77         @Override
 78         public boolean onCreateActionMode(ActionMode mode, Menu menu) {
 79             //创建ActionMode
 80             //使用资源文件填充
 81             MenuInflater inflater = mode.getMenuInflater();
 82             inflater.inflate(R.menu.contextmenu, menu);
 83             return true;
 84         }
 85 
 86         @Override
 87         public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
 88             //获取选项中下表
 89             int position=(Integer)mode.getTag();
 90             switch (item.getItemId()) {
 91             case R.id.context_copy:
 92                 Toast.makeText(ActionModeMenu1.this, "copy "+dataList.get(position), Toast.LENGTH_SHORT).show();
 93                 //finish退出ActionMode模式
 94                 mode.finish();
 95                 return true;
 96             case R.id.context_delete:
 97                 Toast.makeText(ActionModeMenu1.this, "delete "+dataList.get(position), Toast.LENGTH_SHORT).show();
 98                 mode.finish();
 99                 return true;
100             case R.id.context_edit:
101                 Toast.makeText(ActionModeMenu1.this, "edit " +dataList.get(position), Toast.LENGTH_SHORT).show();
102                 mode.finish();
103                 return true;
104             default:
105                 return false;
106         }
107         }
108     };
109     
110     
111 }
复制代码

 效果展示,Android4.0:

 

 

PopupMenu

  PopupMenu,弹出菜单,一个模态形式展示的弹出风格的菜单,绑在在某个View上,一般出现在被绑定的View的下方(如果下方有空间)。

  使用PopupMenu的步骤:

  1. 通过PopupMenu的构造函数实例化一个PopupMenu对象,需要传递一个当前上下文对象以及绑定的View。
  2. 调用PopupMenu.setOnMenuItemClickListener()设置一个PopupMenu选项的选中事件。
  3. 使用MenuInflater.inflate()方法加载一个XML文件到PopupMenu.getMenu()中。
  4. 在需要的时候调用PopupMenu.show()方法显示。

  示例:

复制代码
 1     public void showPopup(View v){
 2         PopupMenu popup=new PopupMenu(MainActivity.this, v);
 3         popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
 4             
 5             @Override
 6             public boolean onMenuItemClick(MenuItem item) {
 7                 switch (item.getItemId()) {
 8                 case R.id.context_copy:
 9                     Toast.makeText(MainActivity.this, "select copy ", Toast.LENGTH_SHORT).show();
10                     return true;
11                 case R.id.context_delete:
12                     Toast.makeText(MainActivity.this, " select delete ", Toast.LENGTH_SHORT).show();
13                     return true;
14                 case R.id.context_edit:
15                     Toast.makeText(MainActivity.this, " select edit ", Toast.LENGTH_SHORT).show();
16                     return true;
17                     default :
18                     return false;
19                 }
20             }
21         });
22         popup.getMenuInflater().inflate(R.menu.contextmenu,popup.getMenu());
23         popup.show();
24     }
复制代码

  效果展示,Android4.0:

  源码下载

总结

  以上就讲解了Android下Menu的使用。因为上面的所有示例均在一个项目中完成的,所以有些低版本的操作,需要更改AndroidManifest.xml文件中的最低支持版本,改到8即可。在现在的实际开发中,最好还是使用对高版本只是的ActionBar、ActionMode、PopupMenu比较好。




本文转自承香墨影博客园博客,原文链接:http://www.cnblogs.com/plokmju/p/android_Menus.html,如需转载请自行联系原作者


相关文章
|
XML Android开发 数据格式
|
14天前
|
开发工具 Android开发 iOS开发
探索Android与iOS开发的差异与挑战
【7月更文挑战第11天】在移动应用开发的广阔天地中,Android和iOS两大平台如同双子星座般耀眼,各自拥有独特的开发生态和用户群体。本文将深入分析这两个平台的显著差异,从技术架构到开发工具,再到市场定位,揭示它们之间的异同。通过比较,我们不仅能够更好地理解各自的优势和局限,还能洞察未来移动应用开发的趋势。
|
17天前
|
Java Android开发 iOS开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
【7月更文挑战第8天】在移动应用开发的广阔天地中,Android与iOS两大平台各自占据着半壁江山。本文将深入探讨这两个平台在开发环境、用户界面设计、性能优化以及市场覆盖等方面的根本差异,并分析这些差异如何影响项目的成功。通过比较和分析,旨在为开发者在选择平台时提供更全面的视角,帮助他们根据项目需求和目标市场做出更明智的决策。
|
10天前
|
Android开发 Kotlin
kotlin开发安卓app,如何让布局自适应系统传统导航和全面屏导航
使用`navigationBarsPadding()`修饰符实现界面自适应,自动处理底部导航栏的内边距,再加上`.padding(bottom = 10.dp)`设定内容与屏幕底部的距离,以完成全面的布局适配。示例代码采用Kotlin。
47 15
|
1天前
|
前端开发 Android开发 iOS开发
探索安卓与iOS开发的差异性与互补性
在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统各据一方,引领着市场潮流。它们在技术架构、开发环境及用户群体等方面展现出独特的差异性,同时也存在着潜在的互补性。本文将深入剖析这两种平台的开发细节,从不同角度揭示其各自优势及相互之间的协同潜力,为开发者提供全面而深刻的视角。
8 2
|
8天前
|
Java Android开发 iOS开发
探索安卓与iOS开发的差异性与互操作性
【7月更文挑战第17天】在移动应用开发的广阔天地中,安卓和iOS这两大操作系统如同双子星座般璀璨夺目。它们各自拥有独特的开发环境、编程语言和用户群体,为开发者提供了不同的挑战和机遇。本文将从多个维度深入剖析安卓与iOS开发的差异性,并探讨它们之间的互操作性如何实现,以期为开发者们提供一份实用的指南。
21 7
|
6天前
|
Java Android开发 Swift
探索iOS与安卓开发的差异与挑战
本文深入探讨了iOS和安卓两大移动操作系统在应用开发领域的不同点及其所面临的挑战。通过对开发环境、编程语言、用户界面设计、性能优化及市场策略的比较分析,揭示了各自平台的独特性以及开发者需要克服的技术与市场障碍。 【7月更文挑战第19天】
|
5天前
|
Java Android开发 iOS开发
探索安卓与iOS开发的差异:平台特性与用户体验的对比分析
【7月更文挑战第19天】在移动开发的广阔天地中,安卓与iOS两大阵营各据一方,它们在开发环境、用户界面设计、性能优化等方面展现出独特的魅力与挑战。本文旨在深入探讨这两个平台在技术开发和用户体验上的根本差异,并分析这些差异如何影响开发者的策略和最终用户的选择。通过比较两者的编程语言、工具、框架以及设计理念,我们将揭示各自平台的优势与局限,为开发者提供实用的参考,并为消费者呈现一个更加清晰的平台选择视角。
|
10天前
|
存储 API Android开发
kotlin开发安卓app,使用webivew 触发 onShowFileChooser, 但只能触发一次,第二次无法触发,是怎么回事。 如何解决
在Android WebView开发中,`onShowFileChooser`方法用于开启文件选择。当用户只能选择一次文件可能是因为未正确处理选择回调。解决此问题需确保:1) 实现`WebChromeClient`并覆写`onShowFileChooser`;2) 用户选择文件后调用`ValueCallback.onReceiveValue`传递URI;3) 传递结果后将`ValueCallback`设为`null`以允许再次选择。下面是一个Kotlin示例,展示如何处理文件选择和结果回调。别忘了在Android 6.0+动态请求存储权限,以及在Android 10+处理分区存储。
|
7天前
|
安全 Java Android开发
探索安卓与iOS开发的差异:构建未来应用的关键考量
【7月更文挑战第18天】在移动应用开发的广阔天地中,安卓和iOS两大平台各领风骚。本文将深入探讨这两个平台在开发过程中的主要差异,包括编程语言、用户界面设计、性能优化、安全性以及市场策略等方面。通过比较分析,旨在为开发者提供决策支持,帮助他们选择最适合自己项目需求的平台,同时考虑到用户体验和市场需求的变化,为未来的应用开发指明方向。