讲作业
话说这次的作业是设计一个布局:
这大概也是之前学过的了,直接贴一下代码吧:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/icon"
android:layout_centerHorizontal="true"
android:background="@drawable/ic_magnify"
android:gravity="center"
android:paddingTop="500dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/icon"
android:orientation="horizontal">
<EditText
android:id="@+id/edittext"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:hint="请输入关键词或网址" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/ic_send" />
</LinearLayout>
TIPS: EditText 可以通过「android:hint="提示词"」来设置提示词,在用户输入内容时提示词会自动消失;在清空输入框时,提示词又会重写出现
最外层的布局是一个相对布局,LOGO 的图片固定大小为 100dp*100dp ,距离顶端 500dp,对齐方式为居中。然后紧接着一个水平的线性布局宽填充父布局,高为适应大小。然后在线性布局里放置一个 EditText,一个 ImageView 。其中 EditText 高度和 ImageView 的高度相同都是 50dp ,因为那个小飞机是正方形,所以 ImageView 的宽也设置为 50dp 这也都不难。重点是,他需要背后的逻辑,我们需要让他输入关键词之后,该搜索的搜索,该跳转的跳转。
Intent 活动之间的桥梁
随着应用的开发,一个活动肯定解决的不了问题,那么就需要建立多个活动。不过打开程序时都是启动的主活动,如果要启动别的活动就需要使用 Intent 了。
显式 Intent
我们昨天已经讲过了怎么创建活动。我们依旧还是在 com.intent.test 包上右键~new~Activity~Empty Activity,弹出新建活动的窗口,我们呢这次就把新建的活动叫做 「webview_activity」,记得这次勾选 Generate Layout File 让 AS 为我们自动创建布局文件,然后在「Layout File」中给布局布局文件起一个名字,就叫「activity_webview」吧。点击 Finish 结束:
随后就可以看到创建好的布局和 Java 文件:
然后我们配置下 MainActivity.java ,为那个小飞机加一个点击事件来跳转到 webview_activity:
ImageView search = (ImageView)findViewById(R.id.search);
search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, webview_activity.class);
startActivity(intent);
}
});
Intent 翻译成中文就是意图的意思。Intent 的构造函数需要传入两个参数,第一个是当前活动的上下文,通常传入当前「类名.this」就行。第二个参数需要传入要启动的目标活动,通常传入「目标活动类名.class」即可。这样我们就构造出了我们要启动一个名字叫「webview_activity」的活动,意图很明显。这样的方式就叫做显示 Intent 。我们调用类提供「startactivity();」方法并传入 Intent 对象就可以启动另一个活动。现在我们重新运行程序,点击小飞机就会发现成功的跳转到了另一个活动:
现在来完善一下我们的新活动,在布局里放入一个 WebView 就行:
<!--文件:webview_activity.xml -->
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/webview"/>
然后修改 Java 文件:
public class webview_activity extends AppCompatActivity {
String HOMEPAGE = "https://bing.com";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview);
WebView webView = (WebView)findViewById(R.id.webview);
initWebView(webView);
webView.loadUrl(HOMEPAGE);
}
void initWebView(WebView webView){
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
//设置在当前窗口打开网页
view.loadUrl(request.toString());
return true;
}
@Override
//拦截唤醒本地app
public void onPageStarted(WebView view, String url, Bitmap favicon){
if (url.startsWith("intent") || url.startsWith("INTENT")) view.loadUrl(url);
}
});
//设置支持JavaScript
webView.getSettings().setJavaScriptEnabled(true);
}
}
最后别忘了加入联网权限
<uses-permission android:name="android.permission.INTERNET"/>
运行的效果如下:
传递数据到下一个活动
话说这也不行呀,我得把我输入的关键词传递给下一个活动。于是我们就需要用 Intent 把数据传递给下一个活动。修改MainActivity.java 中 ImageView 点击事件的代码:
Intent intent = new Intent(MainActivity.this, webview_activity.class);
EditText editText = (EditText)findViewById(R.id.edittext);
intent.putExtra("InputWord",editText.getText().toString());
startActivity(intent);
这里我们利用 Intent.putExtra() 方法来把用户输入的文本暂存到 Intent 里。这里接收两个参数,第一个是「键」,第二个是要传递的数据。键说白了就是你给暂存的数据起一个名字,就好比在论坛中的 ID 一样。因为 Intent 能传递多个数据,要给每一个数据起一个名字。然后我们修改 webview_activity.java 中的逻辑,在 setContentView() 后加入以下的代码,来在第一时间获取 Intent 中的值:
Intent intent = getIntent();
String inputText = intent.getStringExtra("InputText");
首先可以通过 getIntent 来获取启动了这个活动的 Intent ,然后调用 getStringExtra(键值) 来获取 Intent 中的数据。因为我们刚才存放的是字符串,所以这里用 getStringExtra 。如果存放的是整数,那么可以用 getIntExtra,同样如果是布尔值,那么就是 getBooleanExtra。我们继续完善:
if (TextUtils.isEmpty(inputText)){ //验证获取到的用户输入是否为空
//如果用户啥都没输入,就加载主页
webView.loadUrl(HOMEPAGE);
} else{
if (inputText.startsWith("http") || inputText.startsWith("HTTP")){ //验证是否是网址
webView.loadUrl(inputText); //是网址就直接加载
} else {
String result = "https://www.baidu.com/s?wd=" + inputText; //不是网址就拼接出百度搜索链接
webView.loadUrl(result); //加载拼接出的链接
}
}
在获取用户输入的内容后,先验证用户的输入是否为空,是空的话就加载主页。如果不为空就判断是否是网址,是网址就直接丢给 webview 去加载,要是不是网址就拼接出百度的搜索链接。逻辑也比较好理清。下面就贴一下完整的代码:
/** 文件:webview_activity.java **/
public class webview_activity extends AppCompatActivity {
String HOMEPAGE = "https://m.baidu.com";
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview);
Intent intent = getIntent();
String inputText = intent.getStringExtra("InputText");
webView = (WebView)findViewById(R.id.webview);
initWebView(webView);
if (TextUtils.isEmpty(inputText)){
//如果用户啥活都没输入,就加载主页
webView.loadUrl(HOMEPAGE);
} else{
if (inputText.startsWith("http") || inputText.startsWith("HTTP")){
webView.loadUrl(inputText);
} else {
String result = "https://www.baidu.com/s?wd=" + inputText;
webView.loadUrl(result);
}
}
}
void initWebView(WebView webView){
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
//设置在当前窗口打开网页
view.loadUrl(request.toString());
return true;
}
@Override
//拦截唤醒本地app等不是浏览器该做的事
public void onPageStarted(WebView view, String url, Bitmap favicon){
Log.d("webview", "onPageStarted: "+url);
if (url.startsWith("intent") || url.startsWith("INTENT")) {
view.loadUrl(url);
}
}
});
//设置支持JavaScript
webView.getSettings().setJavaScriptEnabled(true);
}
/** 文件:MainActivity.java **/
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
ImageView search = (ImageView)findViewById(R.id.search);
search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, webview_activity.class);
EditText editText = (EditText)findViewById(R.id.edittext);
intent.putExtra("InputText",editText.getText().toString());
startActivity(intent);
}
});
}
}
效果图:
总结
今天我们学了显式 intent,明天我们搞隐式的。不过有一个问题值得考虑,这个浏览器没法后退,这个问题就当作业吧,下课。
2020/5/24 注:
这是我 2018 年高中毕业的假期写的,当时并没有自己搭建博客,近期我给这一系列的文章都放到我自己的博客上。
当时写这个系列文章的想法就是扎实下基础,然后能帮到更多的人就更好了,但是大学开学之后就开始了新生活,没有大块的时间去编撰,系列文章也没有再更新过。但是我其实并不想放弃这个系列,那就,有缘再见吧,拜拜ヾ(•ω•`)o