我的首个电子书软件--嘎嘎读书 的开发(六)

       最近比较忙啊~一直没时间接着写呀,今天讲下目录页和下载模块吧~

       首先是目录页,截图如下

目录

         典型的listview应用~你会发现listview在andorid应用中灰常好用啊~嗯!真好用!

         目录页只需将一本书的目录数据解析 然后将信息展现到item中就可以了,当然点击item时要绑定 链接到阅读页对应章节的功能,这个以后再说~首先是目录页的布局文件。


   
   

   
   
	
    
    
        
     
     
        
     
     

    
    
    
    
    
    
        
     
     
        
     
     
    
    
    
    
    
    
		
     
     
		
     
     
    
    
    

   
   
        对应的activity文件如下,其中重点当然还是 getview方法。因为太简单了 所以我就不细说了。大家有什么地方看不懂留言就可以了。

package com.prince.gagareader;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONException;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo.State;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.prince.gagareader.bean.MuluBean;
import com.prince.gagareader.util.DateProvider;
import com.umeng.analytics.MobclickAgent;

public class MuluActivity extends Activity{
	private Handler handler;
	private String nid;
	private int cid;
	private String novelName;
	
	private ListView muluListView;
	private List
   
   
    
     muluBeanList;
	private Button backButton;
	private TextView titleView;
	private LinearLayout loading;
	private MuluAdapter muluAdapter;
	private boolean isreading;
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mulu);
        initHandler();
        initData();
        initView();
        addListenner();
    }
	private void initHandler(){
		handler = new Handler(){
			@Override  
            public void handleMessage(Message msg) {
				 super.handleMessage(msg);  
	                switch (msg.what) {  
	                case 1:
	                	loading.setVisibility(View.GONE);
	                	muluListView.setSelection(cid-1);
	                	muluAdapter.setSelectItem(cid-1);
	                	muluAdapter.notifyDataSetChanged();
	                	break;
	                case 2:
	                	break;
	                default:  
	                    break;  
	                }  
			}
		};
	}
	private void initData(){
		Intent intent = this.getIntent();
		nid = intent.getStringExtra("nid");
		novelName = intent.getStringExtra("novelName");
		isreading = intent.getBooleanExtra("isreading", false);
		if(novelName==null){
			novelName = "Ŀ¼";
		}
		cid = intent.getIntExtra("cid", 1);
		
		muluBeanList = new ArrayList
    
    
     
     ();
		new Thread(new Runnable() {
			@Override
			public void run() {
				String netState = getNetWorkCate();
				boolean flag = false;
				if(!"none".equals(netState)){
					flag = true;
				}
				try {
					muluBeanList = DateProvider.getInstance().getMuluBeanListByNid(nid, flag);
					sendMessage(1);
				} catch (IOException e) {
					e.printStackTrace();
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
		}).start();
	}
	private void initView(){
		backButton = (Button)findViewById(R.id.btn_leftTop);
		titleView = (TextView)findViewById(R.id.tv_head);
		loading = (LinearLayout)findViewById(R.id.bottom_linear);
		titleView = (TextView)findViewById(R.id.tv_head);
		titleView.setText(novelName);
		muluListView = (ListView)findViewById(R.id.indexLv);
		muluAdapter = new MuluAdapter();
		muluListView.setAdapter(muluAdapter);
	}
	private void addListenner(){
		muluListView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView
     
      arg0, View arg1, int index,
					long arg3) {
				muluAdapter.setSelectItem(index);
            	muluAdapter.notifyDataSetChanged();
            	MuluBean muluBean = muluBeanList.get(index);
            	String nid = muluBean.getNid();
            	int cid = muluBean.getCid();
            	Intent intent = new Intent(MuluActivity.this,
						ReaderActivity.class);
				intent.putExtra("nid", nid);
				intent.putExtra("currentChapter", cid+"");
            	if(isreading){
            		setResult(RESULT_OK, intent);
            		MuluActivity.this.finish();
            	}else{
            		startActivity(intent);
            	}
			}
		});
		backButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				MuluActivity.this.finish();
			}
		});
	}
	class MuluAdapter extends BaseAdapter{
		private int selectIndex=0;
		@Override
		public int getCount() {
			return muluBeanList.size();
		}
		@Override
		public Object getItem(int arg0) {
			return muluBeanList.get(arg0);
		}
		@Override
		public long getItemId(int arg0) {
			return arg0;
		}

		@Override
		public View getView(int index, View conventView, ViewGroup arg2) {
			if(conventView == null){
				conventView = LayoutInflater.from(MuluActivity.this).inflate(R.layout.mulu_item, null);
			}
			LinearLayout selectLiner = (LinearLayout)conventView.findViewById(R.id.select_item);
			if(index==selectIndex){
				selectLiner.setBackgroundColor(Color.RED);
			}else{
				selectLiner.setBackgroundColor(Color.WHITE);
			}
			MuluBean muluBean = muluBeanList.get(index);
			String title = muluBean.getTitle();
			TextView titleTv = (TextView)conventView.findViewById(R.id.muluName);
			titleTv.setText(title);
			return conventView;
		}
		public void setSelectItem(int index){
			selectIndex = index;
		}
	}
	
	private String getNetWorkCate(){
        ConnectivityManager conMan = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        State mobile = conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
        State wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
        if(mobile==State.CONNECTED||mobile==State.CONNECTING)
            return "3g";
        if(wifi==State.CONNECTED||wifi==State.CONNECTING)
            return "wifi";
        return "none";
	}
	
	private void sendMessage(int msgwhat){
		Message message = new Message();  
        message.what = msgwhat;
        handler.sendMessage(message);
	}
	
	public void onResume() {
		super.onResume();
		MobclickAgent.onResume(this);
	}
	public void onPause() {
		super.onPause();
		MobclickAgent.onPause(this);
	}
}

    
    
   
   
        当然 这里与item对应的数据模型类 我称为MuluBean 里面的信息是 小说id 章节id 还有章节名称,muluBean如下:

package com.prince.gagareader.bean;

public class MuluBean {
	private String nid;
	private int cid;
	private String title;
	public String getNid() {
		return nid;
	}
	public void setNid(String nid) {
		this.nid = nid;
	}
	public int getCid() {
		return cid;
	}
	public void setCid(int cid) {
		this.cid = cid;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public MuluBean(String nid, int cid, String title) {
		super();
		this.nid = nid;
		this.cid = cid;
		this.title = title;
	}
	
}

       下一个模块是下载模块,主要是响应简介页的全本下载而生,也是必要组成部分吧,需要的知识储备是  线程,Notification,如果您不是很了解Notification,先去度娘一下吧,先看下效果图

下载

        编写的思路是,首先肯定是线程下载,并定时触发进度更新,这里用android 的handler来处理消息传递,Notification 接到通知之后,更新通知栏状态。下面是下载模块的文件,是用 android的service来承载的。

package com.prince.gagareader.services;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONException;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.RemoteViews;

import com.prince.gagareader.GagaReaderActivity;
import com.prince.gagareader.R;
import com.prince.gagareader.bean.BookBean;
import com.prince.gagareader.bean.DownLoadNotificationBean;
import com.prince.gagareader.util.DateProvider;
import com.prince.gagareader.util.NovelUtil;

public class DownLoadService extends Service{
	private int notificationId=0;
	private Map
   
   
    
     nid_id;
	private Handler handler;
	private NotificationManager manager;
	@Override
	public void onCreate() {
		nid_id=new HashMap
    
    
     
     ();
		manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
		handler = new Handler(){
			@Override  
            public void handleMessage(Message msg) {
				 super.handleMessage(msg);  
	                switch (msg.what) {  
	                case 1:
	                	DownLoadNotificationBean downloadBean = (DownLoadNotificationBean)msg.obj;
	                	Notification notification = downloadBean.getNotification();
	                	int proccess = downloadBean.getProccess();
	                	notification.contentView.setTextViewText(R.id.novelName, downloadBean.getName());
	                	if(proccess==100){
	                		notification.contentView.setTextViewText(R.id.content_view_text1, "下载完毕");
	                	}else{
	                		notification.contentView.setTextViewText(R.id.content_view_text1, proccess+"%");
	                	}
	                	notification.contentView.setProgressBar(R.id.content_view_progress, 100, proccess, false); 
	                	manager.notify(downloadBean.getId(),notification);
	                	break;
	                case 2:
	                	break;
	                default:  
	                    break;  
	                }  
			}
		};
	}
	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}
	
	public void onStart(Intent intent, int startId) {
		Log.e("onstart", "start");
		String nid = intent.getStringExtra("nid");
		String novelName = intent.getStringExtra("novelName");
		int begin = intent.getIntExtra("begin", 1);
		Integer notificationId = nid_id.get(nid);
		if(notificationId!=null){
			
		}else{
			notificationId = this.notificationId++;
			nid_id.put(nid, notificationId);
			Notification notification = initNotification(notificationId, novelName);
			DownLoadNotificationBean downloadBean = new DownLoadNotificationBean(notificationId, novelName, notification);
			manager.notify(downloadBean.getId(),notification);
			new DownLoadThread(nid, begin, downloadBean).start();
		}
	}
	
	private Notification initNotification(int notificationId,String novelName){
		Notification notification =new Notification(notificationId,novelName, System.currentTimeMillis());
		notification.icon = R.drawable.icon;
		//notification.flags |= Notification.FLAG_ONGOING_EVENT; // 将此通知放到通知栏的"Ongoing"即"正在运行"组中  
		notification.contentView = new RemoteViews(getPackageName(), R.layout.nofitication); 
		notification.contentView.setTextViewText(R.id.novelName, novelName);
		notification.contentView.setTextViewText(R.id.content_view_text1, "0%");
		notification.contentView.setProgressBar(R.id.content_view_progress, 100, 0, false); 
		Intent notificationIntent =new Intent(DownLoadService.this, GagaReaderActivity.class); // 点击该通知后要跳转的Activity  
		notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
		PendingIntent contentItent = PendingIntent.getActivity(this, 0, notificationIntent, 0);  
		notification.contentIntent = contentItent;
		return notification;
	}
	
	class DownLoadThread extends Thread{
		private String nid;
		private int begin;
		private BookBean bookBean;
		private DownLoadNotificationBean downloadBean;
		public DownLoadThread(String nid,int begin,DownLoadNotificationBean downloadBean){
			this.nid = nid;
			this.begin = begin;
			this.downloadBean = downloadBean;
		}
		public void run(){
			try {
				bookBean = DateProvider.getInstance().getBookBeanByNid(nid);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			}
			try {
				Thread.sleep(500);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
			int allChapter = bookBean.getAllChapterCount();
			if(begin>=allChapter)return;
			for(int i=begin;i<=allChapter;i++){
				try {
					boolean flag = NovelUtil.getInstance().downloadNovelByNidCid(nid, i+"");
					int proccess = i*100/allChapter;
					if(flag&&proccess!=downloadBean.getProccess()){
						downloadBean.setProccess(proccess);
						sendMessage(1, downloadBean);
						continue;
					}
					if(proccess==100){
						downloadBean.setProccess(proccess);
						sendMessage(1, downloadBean);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private void sendMessage(int msgwhat,DownLoadNotificationBean downloadBean){
		Message message = new Message();  
        message.what = msgwhat;
        message.obj = downloadBean;
        handler.sendMessage(message);
	}
}

    
    
   
   
       值得注意的是,进度的计算方式,因为我小说的数据源接口是以章节为单位的小文件,所以不能以实际下载大小来计算进度,只能以已经下载章节和全部章节数来作为下载进度的标志。另一个需要注意的地方是,当进度的变化超过1%的时候,才会通知通知栏更新ui,这样做事避免通知栏的卡死。如果没下载一章就更新一次通知栏,会使通知栏停止响应。还有就是不同书会采取多线程的方式同时下载,当然,这里没有做线程数的限制,而分配NotificationId的方式也是最简单的递增方式。

       以上就是下载模块,鉴于最近工作比较繁忙,讲解会比较简单,有兴趣的同学可以私信我索要源码,我会将除数据源外的其他部分发送。数据源涉及隐私保护,不能共享,请见谅~ 下一篇文章 我们讲搜索页好了~


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值