Android网络:开发浏览器(三)——功能完善之历史功能

书签的功能已经完成了,那么现在开始就是历史的功能模块。

   

    因为为了方便于数据的管理,所以在原有的书签管理的基础上,进行了相应的修改,通过这个修改,可以使得我们能够同时管理书签和历史。

    自然还是数据管理的接口的修改:

   

package com.example.database;

 

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

public interface IDatabase {

   /**

    * 增加

    * @param sqLiteDatabase 数据库

    * @param tableName  

    * @param name 

    * @param url  地址

    * @param date 日期

    * */

   public boolean add(SQLiteDatabase sqLiteDatabase, String tableName,String name, String url,long date);

  

   /**

    * 删除

    * @param sqLiteDatabase 数据库

    * @param tableName  

    * @param id   书签ID

    * */

   public boolean delete(SQLiteDatabase sqLiteDatabase, String tableName,String id);

  

   /**

    * 删除所有

    * @param sqLiteDatabase 数据库

    * @param tableName  

    * */

   public boolean deleteAll(SQLiteDatabase sqLiteDatabase, StringtableName);

  

   /**

    * 修改

    * @param sqLiteDatabase 数据库

    * @param tableName  

    * @param id   修改的ID

    * @param name 修改后的名

    * @param url  修改后的地址

    * */

   public boolean modify(SQLiteDatabase sqLiteDatabase, String tableName,String id, String name, String url);

  

   /**

    * 获取所有

    * @param sqLiteDatabase 数据库

    * @param tableName  

    * @return   Cursor

    * */

   public Cursor getAll(SQLiteDatabase sqLiteDatabase, StringtableName);

  

   /**

    * 查询某个书签是否存在,即查询url是否重复

    * @param tableName  

    * @param sqLiteDatabase 数据库

    * @param url  地址

    * */

   public boolean multiply(SQLiteDatabase sqLiteDatabase, StringtableName, String url);

   /**

    * 开始事务

    * @param readOnly是否只读

    * @param callback函数回调

    * */

   void transactionAround(boolean readOnly, CallBack callback);

}

代码片段10.2.19 修改后的数据接口

注意,我们可以看到,我在这里添加了一个String的参数,这个参数的形参名为tableName,即是用来分别是对书签还是历史进行操作。

 

至于数据管理的实现,基本没有什么变更,将原本固定的数据表改为变量tableName即可。不过,因为数据的表示不一样,历史相对于书签来说多了个字段就是日期,历史可以通过这个日期来划分组,不过现阶段对这个不做处理。

       

@Override

   public boolean add(SQLiteDatabase sqLiteDatabase, String tableName,String name, String url,long date) throws SQLException{

      ContentValues values = new ContentValues();

      values.put("name", name);

      values.put("url", url);

      if(tableName.equals(FavAndHisManager.TABEL_NAME_Favorite)){

         Log.d(DEG_TAG,"name:"+name+",url:"+url);

      }else{

         values.put("date", date);

         Log.d(DEG_TAG,"name:"+name+",url:"+url+",date:"+date);

      }

      long id = sqLiteDatabase.insert(tableName,null, values);

      if(id!=-1){

         return true;

      }else{

         return false;

      }

   }

   //新增的方法,用来清空历史

   @Override

   public boolean deleteAll(SQLiteDatabase sqLiteDatabase, StringtableName) {

      Log.d(DEG_TAG,"deleteAll");

      int number = sqLiteDatabase.delete(tableName,null, null);

      Log.d(DEG_TAG,"deleteAll_result:"+number);

      if(number!=0){

         return true;

      }else{

         return false;

      }

   }

@Override

   public Cursor getAll(SQLiteDatabase sqLiteDatabase, StringtableName) {

      String[] returnColmuns = null;

      if(tableName.equals(FavAndHisManager.TABEL_NAME_Favorite)){

         returnColmuns = new String[]{

                "id as_id",

                "name",

                "url"

         };

      }else{

         returnColmuns = new String[]{

                "id as_id",

                "name",

                "url",

                "date"

         };

      }

      Cursor result = sqLiteDatabase.query(tableName, returnColmuns,null, null,null, null,null);

      while(result.moveToNext()){

         String id = String.valueOf(result.getInt(result.getColumnIndex("_id")));

         String name = result.getString(result.getColumnIndex("name"));

         String url = result.getString(result.getColumnIndex("url"));

         if(tableName.equals(FavAndHisManager.TABEL_NAME_Favorite)){

            Log.d(DEG_TAG,"id:"+id+",name:"+name+",url:"+url);

         }else{

            String date = String.valueOf(result.getLong(result.getColumnIndex("date")));

            Log.d(DEG_TAG,"id:"+id+",name:"+name+",url:"+url+",date:"+date);

         }

      }

      return result;

   }

代码片段10.2.20 需要修改的方法

   

   

    这里的新增的方法有个清空历史,因为我们在操作浏览器的时候,往往会清空一些历史数据,来释放空间。

    而修改的两个方法前者是因为插入的时候列不同需要处理,后者是因为返回的时候历史界面需要额外的有一个date日期列。

   

    处理好了这个,该是处理历史事务的时候了,其实也就是调用上述的数据管理。

       

/**

    * 增加历史

    * @param name 历史名

    * @param url  历史地址

    * @param date 存放历史时间

    * */

   public boolean addHistory(final String name,final String url, finallong date) {

      flag = false;

      this.database.transactionAround(false,new CallBack() {

        

         @Override

         public voiddoSomething(SQLiteDatabase sqLiteDatabase) {

            //历史可重复,不重复的为iddate

            flag = database.add(sqLiteDatabase, TABEL_NAME_History, name, url, date);

         }

      });

      Log.d(DEG_TAG,"result:"+flag);

      return flag;

   }

  

   /**

    * 删除历史

    * @param id   历史ID

    * */

   public boolean deleteHistory(final String id) {

      flag = false;

      this.database.transactionAround(false,new CallBack() {

        

         @Override

         public void doSomething(SQLiteDatabase sqLiteDatabase) {

            flag = database.delete(sqLiteDatabase, TABEL_NAME_History, id);

         }

      });

      return flag;

   }

  

   /**

    * 删除所有历史

    * */

   public boolean deleteAllHistory(){

      flag = false;

      this.database.transactionAround(false,new CallBack() {

        

         @Override

         public void doSomething(SQLiteDatabase sqLiteDatabase) {

            flag = database.deleteAll(sqLiteDatabase, TABEL_NAME_History);

         }

      });

      return flag;

   }

  

   /**

    * 获取所有历史

    * @return   Cursor

    * */

   public Cursor getAllHistories() {

      this.database.transactionAround(true,new CallBack() {

        

         @Override

         public void doSomething(SQLiteDatabase sqLiteDatabase) {

            resultMap = database.getAll(sqLiteDatabase, TABEL_NAME_History);

         }

      });

      return resultMap;

代码片段10.2.21 新增加历史的事务管理

   

    因为数据库都是同一个,所以,我尽量将这个事务的管理整合到了书签事务管理的类中,重新命名这个类为FavAndHisManager。

   

    历史事务管理已经完成,现在就开始进行相关的页面编辑。页面的编辑跟书签的没啥区别,因为我现在并没有以时间进行划分。我们可以先看看效果,也就是书签的编辑效果,就是更改了字体的显示。

   

图10.2.8    编辑菜单长按预览

       

    至于页面的ListView,这个跟书签的ListView保持一致。所以我在这里就不展示了。

   

    下面是历史的ListView的初始化数据的代码:

   

/**

    * 初始化ListViewHistory的数据

    * */

   @SuppressWarnings("deprecation")

   private void initDataHistory() {

      //获取书签管理

      this.favAndHisManager =new FavAndHisManager(this);

      this.favAndHisCursor =this.favAndHisManager.getAllHistories();

      this.favAndHisAdapter =new SimpleCursorAdapter(getApplicationContext(),

            R.layout.list_item,this.favAndHisCursor,

            new String[]{"_id","name","url","date"},

            new int[]{R.id.item_id, R.id.item_name,R.id.item_url,R.id.item_date});

      this.historyContent.setAdapter(this.favAndHisAdapter);

   }

代码片段10.2.22 历史ListView的初始化

   

    长按单击事件基本与书签的相同,只不过是布局的不同以及取出来的组件不同:

   

itemLongClickedPopWindow = new ItemLongClickedPopWindow(FavAndHisActivity.this,

                   ItemLongClickedPopWindow.HISTORY_ITEM_POPUPWINDOW, 200, 200);

         itemLongClickedPopWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.favandhis_activity));

            itemLongClickedPopWindow.showAsDropDown(view, view.getWidth()/2,-view.getHeight()/2);

            TextView deleteHistory = (TextView) itemLongClickedPopWindow.getView(R.id.item_longclicked_deleteHistory);

            TextView deleteAllHistories = (TextView) itemLongClickedPopWindow.getView(R.id.item_longclicked_deleteAllHistories);

            ItemClickedListener itemClickedListener = newItemClickedListener(view);

            deleteHistory.setOnClickListener(itemClickedListener);

            deleteAllHistories.setOnClickListener(itemClickedListener);

代码片段10.2.23 popupwindow的历史弹出菜单

   

    单击事件如下:

   

Intent intent = new Intent();

intent.putExtra("url",((TextView) arg1.findViewById(R.id.item_url)).getText().toString());

setResult(0, intent);

finish();

代码片段10.2.24 ListView的条目单击事件

   

    可以看到这个跟书签的条目单击事件一模一样。另外需要注意的是,如果我们没有点击任何单击事件,而是直接返回,会发现出现NULLPOINTER的空指针错误,这个就是因为没有设置默认的返回码的缘故。没有任何的返回码,自然在父Actiivty的onActivity的方法中接受返回码的时候会报出异常。

    解决这个问题也很简单,我们只需要在onCreate函数中设置如下语句即可:

   

//添加默认返回值

setResult(-1);

代码片段10.2.25 设置默认返回值

   

    当然,还需要在接受返回值的那里进行处理:

   

@Override

protected void onActivityResult(int requestCode,int resultCode, Intent data) {

      switch (resultCode) {

      case -1:

         //不做任何处理

         break;

      case 0:

         webHolder.loadUrl(data.getStringExtra("url"));

         break;

      }

      super.onActivityResult(requestCode, resultCode, data);

   }

   

   

    这样空指针的错误就解决了。

    那么还有一个最重要的问题,在什么时候记录历史呢?我认为,在每个页面加载完成的时候,就可以将这次访问加入,但因为是历史记录的关系,并不需要进行重复性判断(也许需要根据时间来判断,相同的时间前提下不能进行重复添加,不过这个暂时不进行考虑)。

   

@Override

      public void onPageFinished(WebView view, String url) {

         super.onPageFinished(view, url);

         webUrlLayoutInput.setVisibility(View.GONE);

         webUrlLayoutShow.setVisibility(View.GONE);

         inputShow = false;

         webUrlStr.setText(url);

         changeStatueOfWebToolsButton();

         //添加历史

         String date = new SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(newDate()).toString();

         favAndHisManager.addHistory(title, url, Long.parseLong(date));

      }

代码片段10.2.27 添加历史记录在每次访问后

    至此,历史的功能完成。

   

    案例:

    AndroidStudy_web_V2.1_bydddd牛仔

你可能感兴趣的:(IT,Android基础)