尝试用kotlin做一个app

Posted vocus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尝试用kotlin做一个app相关的知识,希望对你有一定的参考价值。

点击新闻列表进入详情页

使用WebView

1.准备工作

现在没有办法把整个网站前端都做出来,就先做一个新闻页面吧。新闻页面也要连接数据库,要使用之前写后台的JDBC类,所以我想可以在原来项目中增加一个“子项目”。那就要调整一下原来项目的结构。

调整后的项目结构是这样的

 

 以下是遇到的问题和解决方法

idea项目重命名

如果出现错误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="作者:&nbsp;&nbsp"+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="作者:&nbsp;&nbsp"+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的主要内容,如果未能解决你的问题,请参考以下文章

尝试用kotlin做一个app

尝试用kotlin做一个app

尝试用kotlin做一个app(十六)

尝试用kotlin做一个app

如何在 Kotlin 片段内的按钮之间切换片段?

如何在kotlin的片段内显示网格视图?