Android GridView项点击实现Chrome自定义标签(含WebView降级)求助
解决GridView项点击打开Chrome自定义标签并降级到WebView的问题
首先看你的代码,目前点击GridView项是重新启动MainActivity,这显然不是你要的效果,而且没有处理Chrome自定义标签的逻辑,另外你的GridView适配器还有个小bug(convertView使用错误)。下面一步步帮你实现需求:
1. 先添加Chrome自定义标签的依赖
在你的Module级别的build.gradle文件中添加依赖(可根据需要替换为最新版本):
implementation 'androidx.browser:browser:1.5.0'
2. 修复GridView适配器的bug
你的CustomGridViewActivity里把convertView定义成了类成员变量,这会导致列表项复用逻辑出错,同时getItem和getItemId返回值不正确,修改后的适配器代码如下:
public class CustomGridViewActivity extends BaseAdapter { private Context mContext; private final String[] gridViewString; private final int[] gridViewImageId; public CustomGridViewActivity(Context context, String[] gridViewString, int[] gridViewImageId) { mContext = context; this.gridViewString = gridViewString; this.gridViewImageId = gridViewImageId; } @Override public int getCount() { return gridViewString.length; } @Override public Object getItem(int position) { return gridViewString[position]; // 返回对应位置的文本数据,而不是null } @Override public long getItemId(int position) { return position; // 返回正确的位置ID } @Override public View getView(int position, View convertView, ViewGroup parent) { View gridViewAndroid; LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // 使用方法参数里的convertView,不要用类成员变量 if (convertView == null) { // 传入parent让布局正确适配父容器 gridViewAndroid = inflater.inflate(R.layout.structure, parent, false); TextView textViewAndroid = gridViewAndroid.findViewById(R.id.gridView_text); ImageView imageViewAndroid = gridViewAndroid.findViewById(R.id.gridView_image); textViewAndroid.setText(gridViewString[position]); imageViewAndroid.setImageResource(gridViewImageId[position]); } else { gridViewAndroid = convertView; } return gridViewAndroid; } }
3. 修改MainActivity的点击逻辑,实现Chrome自定义标签+WebView降级
首先在MainActivity里新增对应每个项的URL数组,然后重写点击事件,添加判断逻辑:如果设备有支持Chrome自定义标签的浏览器,就用它打开链接;否则启动WebView页面作为降级方案。
修改后的MainActivity代码:
public class MainActivity extends AppCompatActivity { GridView gridView; String[] gridViewString = { "Facebook", "Twitter", "Instagram", "Gmail", "Google+"}; // 新增URL数组,对应每个GridView项的链接 String[] gridViewUrls = { "https://www.facebook.com", "https://twitter.com", "https://www.instagram.com", "https://mail.google.com", "https://plus.google.com" }; int[] gridViewImageId = {R.drawable.facebook, R.drawable.twitter, R.drawable.instagram, R.drawable.gmail, R.drawable.googleplus}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); CustomGridViewActivity customGridViewActivity = new CustomGridViewActivity(MainActivity.this, gridViewString, gridViewImageId); gridView = findViewById(R.id.column); gridView.setAdapter(customGridViewActivity); gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { String targetUrl = gridViewUrls[position]; String pageTitle = gridViewString[position]; openUrlWithFallback(targetUrl, pageTitle); } }); } private void openUrlWithFallback(String url, String title) { // 构建Chrome自定义标签的Intent CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); // 可选:设置工具栏颜色,替换成你项目里的颜色 builder.setToolbarColor(ContextCompat.getColor(this, R.color.colorPrimary)); builder.setShowTitle(true); // 显示网页标题 CustomTabsIntent customTabsIntent = builder.build(); // 检查是否有支持Chrome自定义标签的浏览器 PackageManager packageManager = getPackageManager(); Intent testIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); ResolveInfo resolveInfo = packageManager.resolveActivity(testIntent, PackageManager.MATCH_DEFAULT_ONLY); boolean hasCustomTabsSupport = false; if (resolveInfo != null) { String browserPackage = resolveInfo.activityInfo.packageName; // 获取支持自定义标签的浏览器包名 String supportedPackage = CustomTabsClient.getPackageName(this, null); hasCustomTabsSupport = browserPackage.equals(supportedPackage); } if (hasCustomTabsSupport) { // 打开Chrome自定义标签 customTabsIntent.launchUrl(this, Uri.parse(url)); } else { // 降级到WebView页面 Intent webViewIntent = new Intent(this, WebViewActivity.class); webViewIntent.putExtra("URL", url); webViewIntent.putExtra("TITLE", title); startActivity(webViewIntent); } } }
4. 创建WebViewActivity作为降级方案
新建一个WebViewActivity来处理没有自定义标签支持时的网页加载,同时添加返回键逻辑:
public class WebViewActivity extends AppCompatActivity { private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_web_view); // 获取传递的URL和标题 String url = getIntent().getStringExtra("URL"); String pageTitle = getIntent().getStringExtra("TITLE"); setTitle(pageTitle); webView = findViewById(R.id.web_view); // 可选:启用JavaScript,根据你的需求决定 webView.getSettings().setJavaScriptEnabled(true); // 设置WebViewClient,避免跳转到系统浏览器 webView.setWebViewClient(new WebViewClient()); // 加载网页 webView.loadUrl(url); } // 处理返回键,让WebView返回上一页 @Override public void onBackPressed() { if (webView.canGoBack()) { webView.goBack(); } else { super.onBackPressed(); } } }
对应的activity_web_view.xml布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <WebView android:id="@+id/web_view" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
5. 在Manifest中注册WebViewActivity
最后别忘了在AndroidManifest.xml里注册这个Activity:
<activity android:name=".WebViewActivity" android:configChanges="orientation|screenSize"/> <!-- 添加这个属性避免旋转屏幕时WebView重新加载 -->
这样修改后,你的GridView项点击后就会优先打开Chrome自定义标签,如果设备没有支持的浏览器,就会用WebView加载网页啦。
内容的提问来源于stack exchange,提问作者Agam Jain
相关产品推荐
相关产品推荐

