APP开发流程实例讲解-儒释道网络电台八天开发全程-在Android Studio中完成界面设计

APP开发流程实例讲解-儒释道网络电台八天开发全程

功能和界面初步设定

APP开发流程实例讲解-儒释道网络电台八天开发全程

  1. 项目发起
  2. 功能和界面初步设定
  3. 在Android Studio中完成界面设计
  4. 实现功能代码:播放控制
  5. 优化排错:增强稳定性和添加异常处理
  6. 界面美化并进一步优化排错
  7. 百度云深度兼容测试并进一步优化排错
  8. 签名发布



昨天的做的设计图是比较简单的,主要麻烦是需要实现两侧的滑动抽屉菜单。

在Android Studio中有一个模板可以创建左侧抽屉,但儒释道网络电台APP需要两边两个抽屉。在网上找到一篇文章《AndroidDrawerLayout+fragment布局实现左右侧滑 》,是使用FragmentTransaction来实现左右侧栏的显现。还有一种办法是使用第三方组件SlidingMenu。难道就不能用Android Studio模板可以创建两侧抽屉滑动菜单吗?经过我一个多小时的探索和尝试,最终发现是可以的。创建的方法我已经写到另一篇文章《Android DrawerLayout+NavigationView布局实现左右两边侧滑菜单 》,这里不再多说。今天主要的完成的工作有。

双侧滑动抽屉菜单

实现方法上面已经说过,但又略有不同。根据昨天设计的界面,两侧菜单其实是三个ListView,但NavigationView主要是结合menu菜单来创建,有些不对路。经过尝试,最终删掉了NavigationView的menu属性,将列表加入到headerLayout中。实际代码如下:


nav_header_main.xml文件




    

    


    

然后就是在两个header的Layout文件如下:





    

        

        

            

            
        

    

    

        

        
    
    
    

    

        

        
    
    
    





nav_server_header_main.xml




    

        
        
    
    
    



ListView列表项Layout就不贴了。


主界面的设计

如昨天设计图所示的Layout文件如下:




    
    
        
        

            

            

        
    

    

        

            

            
        

        

            

                
            
        

    



根据比例设置视频窗口高度

        FrameLayout player_frame = (FrameLayout) findViewById(R.id.player_frame);
        WindowManager wm = this.getWindowManager();
        int width = wm.getDefaultDisplay().getWidth();
        int height = width * 9 / 16;
        player_frame.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height));

初步完成网络访问API类

网络访问使用了OKHTTP组件,并且是异步访问。OKHttp的使用这里就不多说了。功能实现方法是使用OKHttp下载网页,用正则表达式解析网页,抓取数据生成对象。调用完成事件将数据传回。然后再在UI线程中使用数据填充ListView等。

API类如下

package com.jianchi.fsp.buddhismnetworkradio;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by fsp on 16-7-5.
 */
public class WebApi {

    /*
    节目时间表:
    视频音频播放器
    线路选择:http://www.amtb.tw/tvchannel/play-1-revised.asp
    最新讯息:http://www.amtb.tw/tvchannel/show_marquee.asp
    经文讲义:http://ft.hwadzan.com/mycalendar/mycalendar_embed_livetv.php?calendar_name=livetv
    * */

    private static final String programsListUrl  = "http://ft.hwadzan.com/mycalendar/mycalendar_embed.php?calendar_name=livetv&showview=day&valign=true&bgcolor=none&showtimecolumns=start&tvmenu=3";
    private static final String serversListUrl  = "http://www.amtb.tw/tvchannel/play-1-revised.asp";
    private static final String newsListUrl  = "http://www.amtb.tw/tvchannel/show_marquee.asp";
    private static final String noteUrl  = "http://ft.hwadzan.com/mycalendar/mycalendar_embed_livetv.php?calendar_name=livetv";

    Pattern programsListPattern = Pattern.compile("\\s*(.*?)\\s*(.*?)\\s*");
    Pattern htmlTagPattern = Pattern.compile("<[^>]*>");

    Pattern serversListPattern = Pattern.compile("serverAddress = \"(.*?)\";\\s*serverName = \"(.*?)\";");
    Pattern newsListPattern = Pattern.compile("
(.*?)
"); Pattern noteItemPattern = Pattern.compile("

\\s*(.*?)\\s*

"); private OkHttpClient client = new OkHttpClient(); IProgramsListEvent programsListEvent; IServersListEvent serversListEvent; IProgramsListEvent newsListEvent; IStringEvent noteEvent; public void GetNote(IStringEvent noteEvent) { this.noteEvent = noteEvent; Request request = new Request.Builder() .url(noteUrl) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); WebApi.this.noteEvent.getMsg(null); } @Override public void onResponse(Call call, Response response) throws IOException { String html = new String(response.body().bytes(), "big5"); Matcher m = noteItemPattern.matcher(html); StringBuilder sb = new StringBuilder(); while (m.find()){ String nm = m.group(1); if(nm.startsWith("<")) { Matcher hm = htmlTagPattern.matcher(nm); nm = hm.replaceAll(""); } sb.append(nm).append("\r\n"); } WebApi.this.noteEvent.getMsg(sb.toString()); } }); } public void GetNewsList(IProgramsListEvent newsListEvent) { this.newsListEvent = newsListEvent; Request request = new Request.Builder() .url(newsListUrl) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); WebApi.this.newsListEvent.getItems(null); } @Override public void onResponse(Call call, Response response) throws IOException { String html = new String(response.body().bytes(), "big5"); Matcher m = newsListPattern.matcher(html); List newsList = new ArrayList(); while (m.find()){ String nm = m.group(1); if(nm.startsWith("<")) { Matcher hm = htmlTagPattern.matcher(nm); nm = hm.replaceAll(""); } newsList.add(nm); } WebApi.this.newsListEvent.getItems(newsList); } }); } public void GetProgramsList(IProgramsListEvent programsListEvent) { this.programsListEvent = programsListEvent; Request request = new Request.Builder() .url(programsListUrl) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); WebApi.this.programsListEvent.getItems(null); } @Override public void onResponse(Call call, Response response) throws IOException { String html = new String(response.body().bytes(), "utf-8"); Matcher m = programsListPattern.matcher(html); List programsList = new ArrayList(); while (m.find()){ String nm = m.group(2); if(nm.startsWith("<")) { Matcher hm = htmlTagPattern.matcher(nm); nm = hm.replaceAll(""); } programsList.add(m.group(1) + " " + nm); } WebApi.this.programsListEvent.getItems(programsList); } }); } public void GetServersList(IServersListEvent serversListEvent) { this.serversListEvent = serversListEvent; Request request = new Request.Builder() .url(serversListUrl) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { String html = new String(response.body().bytes(), "utf-8"); Matcher m = serversListPattern.matcher(html); ServersList serverList = new ServersList(); while (m.find()){ serverList.add(new ServerInfo(m.group(1), m.group(2))); } WebApi.this.serversListEvent.getServers(serverList); } }); } }

在UI线程中调用的代码如下

        api = new WebApi();
        api.GetNewsList(new IProgramsListEvent() {
            @Override
            public void getItems(List programs) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }
        });

        api.GetNote(new IStringEvent() {
            @Override
            public void getMsg(String msg) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }
        });

        api.GetProgramsList(new IProgramsListEvent() {
            @Override
            public void getItems(List programs) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }
        });

        api.GetServersList(new IServersListEvent() {
            @Override
            public void getServers(ServersList servers) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }
        });

总的来说写代码用的时间比较少,界面设计不熟悉用时较多。原计划每天花2个小时来做这个APP,但今天实际花有4个多小时。界面代码那里花时间过多了,写JAVA代码反而比较快。


明天按计划,写播放器控制的代码。


所有代码已经上传到GIT:https://code.csdn.net/do168/buddhismnetworkradio

你可能感兴趣的:(Android)