尝试用kotlin做一个app
Posted vocus
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尝试用kotlin做一个app相关的知识,希望对你有一定的参考价值。
点击新闻列表进入详情页
使用WebView
1.准备工作
现在没有办法把整个网站前端都做出来,就先做一个新闻页面吧。新闻页面也要连接数据库,要使用之前写后台的JDBC类,所以我想可以在原来项目中增加一个“子项目”。那就要调整一下原来项目的结构。
调整后的项目结构是这样的
以下是遇到的问题和解决方法
如果出现错误javax.management.InstanceNotFoundException: Catalina:type=Server,查看artifacts下的是否还保留了原来的项目
提示:Caused by: java.lang.IllegalArgumentException: 指定的主资源集无效,查看tomcat下的server.xml下是否存在无效的路径
servlet重定向到jsp后,css样式和图片都没了,解决办法
2.写新闻详情页的html代码&ajax请求数据
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>新闻标题</title> <style type="text/css"> body{ margin:0; padding:0; } .newsheader{ width:1000px; margin:0 auto; background-color:#f2f2f2; padding:0,0,15,0; border-bottom:1px solid #e5e5e5; } h1,h2{ margin:0; padding:0; } .newsheadtitle{ } .headappend{ color:#666; padding-left:10px; } .headappend a{ text-decoration:none; color:#666; } .headappend a:hover{ text-decoration:underline; } .headpubdate{ display:inline-block; } .icon_1{ background: url(icon/icon_comment1.png) bottom no-repeat; width:20px; height:20px; display:inline-block; margin-left:10px; } .headorigin{ padding-left:10px; display:inline-block; } .newscontent{ width:1000px; margin:0 auto; } .newscontent p{ font-size:18px; color:#333; line-height:1.4em; text-indent:2em; margin:0; padding:0; } .newsnote{ font-style:italic; padding:20px 45px 0px 30px; } .newstext{ padding:20px 45px 30px 30px; } .newsediter{ color:#666; font-size:14px !important; display:inline-block; float:right; padding-right:45px !important; } </style> <script type="text/javascript"> window.onload=function(){ loadData(); } function loadData(){ if(window.XMLHttpRequest){ var xmlhttp=new XMLHttpRequest(); }else if(window.ActiveXObject){ xmlhttp=new ActiveXObject(\'Microsoft.XMLHTTP\'); } xmlhttp.onreadystatechange=function(){ var result=xmlhttp.responseText; //var data=eval("("+result+")"); //console.log(result) var data=eval("("+result+")") //console.log(data.result[0].title) var maintitle=data.result[0].title; var content=data.result[0].content; var pubdate=data.result[0].pubdate; var author=data.result[0].author; var href=data.result[0].href; var origin=data.result[0].origin; document.getElementById("maintitle").innerHTML=maintitle; document.getElementById("newstext").innerHTML=content; document.getElementById("newsediter").innerHTML="作者:  "+author; document.getElementById("headorigin").innerHTML=origin document.getElementById("pubdate").innerHTML=(new Date(parseInt(pubdate))).toLocaleString(); }; xmlhttp.open("get","/clientapi/api?news=1",false); xmlhttp.send(null); } </script> </head> <body> <div class="newsheader"> <div class="newsheadtitle"> <h1 id="maintitle"></h2> <h2 id="subtitle"></h3> <div class="headappend"> <span id="pubdate" class="headpubdate"></span> <span class="headorigin" id="headorigin"><a href="#">来源:JustTest</a></span> <span><a href="#" class="icon_1" title="评论"></a></span> <span><a href="#" id="commentCount">3</a></span> </div> </div> </div> <div class="newscontent"> <div class="newsnote"> <p id="newsnote"></p> </div> <div class="newstext" > <p id="newstext"></p> </div> <p class="newsediter" id="newsediter"></p> </div> <div class="newscomment"> <div class="shape"></div> </div> </body> </html>
3.客户端使用webview读取页面
先给recyclerView添加点击事件,用到了闭包的概念(java方法)
定义一个接口
public interface OnItemClickListener{ fun onClick(pos:Int); }
声明接口,并以adapter类的构造参数传入
private var listener:OnItemClickListener?=null constructor(listener:OnItemClickListener):this(){ this.listener=listener }
在实例化adapter的时候,使用回调方法
var adapter=HomePageNewsAdapter(object :HomePageNewsAdapter.OnItemClickListener{
override fun onClick(pos: Int) {
Toast.makeText(context,pos.toString(),Toast.LENGTH_SHORT).show()
}
});
我之前走了一个弯路,把新闻条目之间的分割线也做成recyclerview的条目了。有其他的办法实现分割线。那现在先保持原样吧。
所以在外面加个判断,如果position是0,1,3,5,7,9那就要处理,此外还要把新闻标题列表中的标题也传出来,不然读取数据库会有很多问题,那这个,如果使用newsList(pos)的方式,ArrayList就会越界了。。。
所以在adapter中判断了item的类型之后,再添加item的点击事件(事实应该有六条新闻才对,第一条是由图片索引,其他五条由标题。但是我开始就没考虑第一条,现在暂时也不考虑)
实例化adapter变成这样
override fun initData() { homepage_news_container.layoutManager = LinearLayoutManager(context) var adapter=HomePageNewsAdapter(object :HomePageNewsAdapter.OnItemClickListener{ override fun onClick(pos: Int,title:String?) { //Toast.makeText(context,"位置$pos,标题$title",Toast.LENGTH_SHORT).show() var intent:Intent?=null intent=Intent(context,NewsPageActivity::class.java) intent.putExtra("title",title)
startActivity(intent); } });
在NewsPageActivity中,接收title
class NewsPageActivity:BaseActivity() { override fun getLayoutId(): Int { return R.layout.activity_newspage } override fun initData() { var title=intent.getStringExtra("title"); Toast.makeText(baseContext,"haha$title",Toast.LENGTH_SHORT).show() } }
4.使用WebView加载新闻的html
wv_newsPage.loadUrl("http://局域网地址:8080/client/temp.html") wv_newsPage.webViewClient= WebViewClient() wv_newsPage.settings.javaScriptEnabled=true
这样发现页是很难看的,因为原来的网页太大,导致在客户端中左右都会滚动。解决办法可以参考Android 中Webview 自适应屏幕
我使用的是
wv_newsPage.settings.useWideViewPort=true wv_newsPage.settings.loadWithOverviewMode=true
效果是这样
还是挺难看的,一方面是之前前端的页面做得不好,另一方面,把页面按比例缩小了。但是先不考虑这个了
5.与html通信,传title的值给html5
点击不同的新闻标题,获得到的新闻应该是变化的。在NewsPageActivity中应该把title的值传给html,再在html中动态获取数据库中的新闻
我的天,从前一篇开始,我做的所有准备,都是为了让安卓与html5的一次通信啊。。。
简单的通信是这样
wv_newsPage.settings.useWideViewPort=true wv_newsPage.settings.loadWithOverviewMode=true //wv_newsPage.getSettings().setDomStorageEnabled(true); wv_newsPage.addJavascriptInterface(JavascriptMethods(baseContext,title),"jsInterface");
class JavascriptMethods { private var mContext:Context?=null private var title:String?=null constructor(mContext:Context,title:String){ this.mContext=mContext this.title=title } @JavascriptInterface fun getTitle():String?{ return title } }
html中
var origin=data.result[0].origin; var maintitle=window.jsInterface.getTitle(); document.getElementById("maintitle").innerHTML=maintitle;
现在要在html中改变一下ajax的请求接口:根据标题请求新闻的内容。。
function loadData(){ if(window.XMLHttpRequest){ var xmlhttp=new XMLHttpRequest(); }else if(window.ActiveXObject){ xmlhttp=new ActiveXObject(\'Microsoft.XMLHTTP\'); } xmlhttp.onreadystatechange=function(){ var result=xmlhttp.responseText; var data=eval("("+result+")") //console.log(data.result[0].title) var maintitle=data.result.title; var content=data.result.content; var pubdate=data.result.pubdate; var author=data.result.author; var href=data.result.href; var origin=data.result.origin; document.getElementById("maintitle").innerHTML=maintitle; document.getElementById("newstext").innerHTML=content; document.getElementById("newsediter").innerHTML="作者:  "+author; document.getElementById("headorigin").innerHTML=origin document.getElementById("pubdate").innerHTML=(new Date(parseInt(pubdate))).toLocaleString(); }; var title=window.jsInterface.getTitle(); var str="/clientapi/api?title="+title; xmlhttp.open("get",str,false); xmlhttp.send(null); }
另外请求api随便写一下。这样就可以实现点击首页新闻标题进入新闻详情页显示了。显示的效果不好,下次改善一下。
以上是关于尝试用kotlin做一个app的主要内容,如果未能解决你的问题,请参考以下文章