您的位置:首页 > 理论基础 > 计算机网络

Android网络:开发浏览器(二)——功能完善之书签功能

2013-08-26 02:23 477 查看
经过上述的编写,基本的功能已经完成了,不过工具栏里面基本还是一片空白,只有一个刷新的功能,现在咱们就先完善这些功能(之前有朋友说来点图,那么这次我会截些图更好的来描述)。

 

既然是浏览器,怎么能没有书签的功能,为了操作方便,我就将添加的书签放在地址栏的旁边,我比较喜欢UC,那么就来模仿UC吧☺

UC的功能是在点击地址栏的时候会隐藏其他功能,好了,知道所要做的,那么久开工了。

 

为了布局方便,我先将搜索的按钮也放上去了。我在这里将地址栏的布局放上去:

<FrameLayout
       android:id="@+id/web_url_all"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       >
 
        <LinearLayout
           android:id="@+id/web_url_layout"
           android:layout_width="match_parent"
           android:layout_height="46dp"
           android:background="@android:color/holo_blue_light"
           android:orientation="horizontal"
           android:visibility="gone">
 
            <EditText
                android:id="@+id/web_url_input"
                android:layout_width="0dp"
                android:layout_height="36dp"
                android:layout_marginLeft="5dp"
                android:layout_marginTop="5dp"
                android:layout_weight="0.8"
                android:background="@drawable/search_back"
                android:hint="@string/webUrlHint"
                android:inputType="textUri"
                android:paddingLeft="5dp"
                android:textSize="15sp"/>
 
            <Button
                android:id="@+id/web_url_goto"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="5dp"
                android:layout_weight="0.2"
                android:text="@string/webUrlGoto"
                android:visibility="gone"/>
 
            <Button
                android:id="@+id/web_url_cancel"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="5dp"
                android:layout_weight="0.2"
                android:text="@string/webUrlCancel"/>
        </LinearLayout>
 
        <LinearLayout
           android:id="@+id/web_url_layout_normal"
           android:layout_width="match_parent"
           android:layout_height="46dp"
           android:background="@android:color/holo_blue_light"
           android:baselineAligned="false"
           android:orientation="horizontal">
 
            <LinearLayout
                android:id="@+id/web_url_show"
                android:layout_width="0dp"
                android:layout_height="36dp"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:layout_marginTop="5dp"
                android:layout_weight="0.8"
                android:background="@drawable/search_back"
                android:orientation="horizontal">
 
                <Button
                    android:id="@+id/web_url_show_favorite"
                    android:layout_width="24dp"
                   android:layout_height="24dp"
                    android:layout_margin="5dp"
                    android:background="@drawable/favorites_button"/>
 
                <ImageView
                    android:layout_width="2dp"
                    android:layout_height="27dp"
                    android:layout_marginTop="5dp"
                    android:background="@drawable/url_divider"
                    android:contentDescription="@string/divider"/>
 
                <TextView
                    android:id="@+id/web_url_show_title"
                    android:layout_width="190dp"
                    android:layout_height="27dp"
                    android:layout_margin="5dp"
                    android:hint="@string/webUrlHint"/>
 
                <ImageView
                    android:layout_width="32dp"
                    android:layout_height="25dp"
                    android:layout_marginTop="5dp"
                    android:background="@drawable/search_button"
                   android:contentDescription="@string/divider"/>
 
                <TextView
                    android:id="@+id/web_url_show_search"
                    android:layout_width="30dp"
                    android:layout_height="27dp"
                    android:layout_marginTop="7dp"
                    android:hint="@string/search"/>
            </LinearLayout>
        </LinearLayout>
    </FrameLayout>

代码片段10.2.1  地址栏xml片段
 

其实因为考虑到Android效率问题,我都是通过尽量在一个Activity中展示来实现程序,通过上面的xml我们可以看看效果:



图10.2.1    地址栏更改后的显示效果
 

可以看到,我们的地址栏已经成功展示。这个是通过activity的预览功能来截图的,以前没发现这个功能这么强大好用= =。

既然视图已经完成,那么接下来就是代码的实现。

因为实现的只是书签的收藏功能,所以地址栏的隐藏显示等,就在这里不多说了,大家可以看我上传的具体代码。

 

书签的收藏,我是通过数据库来实现的,所以为了方便操作,我对Cursor数据库进行了基本操作的封装。

首先,咱们定义一个数据库的单元操作接口:

 

package com.example.database;
 
import java.util.HashMap;
 
import android.database.sqlite.SQLiteDatabase;
 
public
interface
IDatabase {
   /**
    * 增加书签
    * @param sqLiteDatabase 数据库
    * @param name 书签名
    * @param url  书签地址
    * */
   public
boolean
addFavorite(SQLiteDatabase sqLiteDatabase, String name,String url);
  
   /**
    * 删除书签
    * @param sqLiteDatabase 数据库
    * @param id   书签ID
    * */
   public
boolean
deleteFavorite(SQLiteDatabase sqLiteDatabase, Stringid);
  
   /**
    * 修改书签
    * @param sqLiteDatabase 数据库
    * @param id   修改的书签ID
    * @param name 修改后的书签名
    * @param url  修改后的书签地址
    * */
   public
boolean
modifyFavorite(SQLiteDatabase sqLiteDatabase, String id,String name, String url);
  
   /**
    * 获取所有书签
    * @param sqLiteDatabase 数据库
    * @return   HashMap<String, String>
    * */
   public HashMap<String, String>getAllFavorites(SQLiteDatabase sqLiteDatabase);
  
   /**
    * 查询某个书签是否存在,即查询url是否重复
    * @param sqLiteDatabase 数据库
    * @param url  书签地址
    * */
   public
boolean
multiplyFavorite(SQLiteDatabase sqLiteDatabase, Stringurl);
  
   /**
    * 开始事务
    * @param readOnly是否只读
    * @param callback函数回调
    * */
   void transactionAround(boolean readOnly, CallBack callback);
}

代码片段10.2.2  数据库接口定义
 

因为为了效率问题,我在这里竟然少使用类,所以,并不像web一样,使用对象处理的方式,而是将字段的值传入。

并且,因为事务的关系,我在这里使用了回调函数,这样可以很方便的进行事务的控制。

 

好了,接口已经定义好了,那么就开始进行接口的实现:

 

package com.example.database;
 
import java.util.HashMap;
 
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
 
public
class
SQLManager extends SQLiteOpenHelperimplements IDatabase{
  
   private
static final
String DEG_TAG ="webBrowser_SQLManager";
 
   public SQLManager(Context context, String name, CursorFactoryfactory,
         int version) {
      super(context, name, factory, version);
   }
 
   @Override
   public
void
onCreate(SQLiteDatabase db) {
      //创建表
      db.execSQL(SQLStr.CREATE_TABLE);
   }
 
   @Override
   public
void
onUpgrade(SQLiteDatabase db, int oldVersion,int newVersion) {
     
   }
 
   @Override
   public
boolean
addFavorite(SQLiteDatabase sqLiteDatabase, String name,String url) {
      ContentValues favorite = new ContentValues();
      favorite.put("name", name);
      favorite.put("url", url);
      long id = sqLiteDatabase.insert("favorite",null, favorite);
      if(id!=-1){
         return
true
;
      }else{
         return
false
;
      }
   }
 
   @Override
   public
boolean
deleteFavorite(SQLiteDatabase sqLiteDatabase, String id){
      int number = sqLiteDatabase.delete("favorite","id=?",
new String[]{id});
      if(number!=0){
         return
true
;
      }else{
         return
false
;
      }
   }
 
   @Override
   public
boolean
modifyFavorite(SQLiteDatabase sqLiteDatabase, String id,String name, String url) {
      ContentValues favorite = new ContentValues();
      favorite.put("name", name);
      favorite.put("url", url);
      int number = sqLiteDatabase.update("favorite", favorite,"id=?",
new String[]{id});
      if(number!=0){
         return
true
;
      }else{
         return
false
;
      }
   }
 
   @Override
   public HashMap<String, String>getAllFavorites(SQLiteDatabase sqLiteDatabase) {
      HashMap<String, String> resultMap = new HashMap<String,String>();
      Cursor result = sqLiteDatabase.query("favorite",null,
null,null,
null,null,
"id");
      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"));
         Log.d(DEG_TAG,"id:"+id+",name:"+name+",url:"+url);
         resultMap.put(id, name+" : "+url);
      }
      return resultMap;
   }
 
   @Override
   public
boolean
multiplyFavorite(SQLiteDatabase sqLiteDatabase, Stringurl) {
      Cursor result = sqLiteDatabase.query("favorite",null,
"url=?", new String[]{url},null,
null,null);
      if(result.getCount()>0){
         return
true
;
      }else{
         return
false
;
      }
   }
  
   @Override
   public
void
transactionAround(boolean readOnly, CallBack callback) {
      SQLiteDatabase sqLiteDatabase = null;
      if(readOnly){
         sqLiteDatabase = this.getReadableDatabase();
      }else{
         sqLiteDatabase = this.getWritableDatabase();
      }
      sqLiteDatabase.beginTransaction();
      callback.doSomething(sqLiteDatabase);
      sqLiteDatabase.setTransactionSuccessful();
      sqLiteDatabase.endTransaction();
   }
 
}

代码片段10.2.3  数据库的实现
       

接口实现完毕,可以进行书签事务的管理了,通过回调函数,来进行选择SQLiteDatabase,并且开始事务的进行。

 

package com.example.other;
 
import java.util.HashMap;
 
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
 
import com.example.database.CallBack;
import com.example.database.IDatabase;
import com.example.database.SQLManager;
 
public
class
FavoritesManager {
  
   private
static final
String DEG_TAG ="webbrowser_FavroitesManager";
  
   private IDatabasedatabase;
   private
boolean
flag = false;
   private HashMap<String, String>resultMap;
  
   public FavoritesManager(Context context){
      this.database =new SQLManager(context,
"favorite", null, 1);
   }
  
   /**
    * 增加书签
    * @param name 书签名
    * @param url  书签地址
    * */
   public
boolean
addFavorite(final String name,final String
url) {
      flag = false;
      this.database.transactionAround(false,new CallBack()
{
        
         @Override
         public
void
doSomething(SQLiteDatabase sqLiteDatabase) {
            boolean ifmultiply =database.multiplyFavorite(sqLiteDatabase, url);
            if(!ifmultiply){
                Log.d(DEG_TAG,"reason:未存在相同书签");
                flag =
database.addFavorite(sqLiteDatabase, name, url);
            }else{
                Log.d(DEG_TAG,"reason:已经存在相同书签");
                flag =
false
;
            }
         }
      });
      Log.d(DEG_TAG,"result:"+flag);
      return
flag;
   }
  
   /**
    * 删除书签
    * @param id   书签ID
    * */
   public
boolean
deleteFavorite(final String id) {
      flag = false;
      this.database.transactionAround(false,new CallBack()
{
        
         @Override
         public
void
doSomething(SQLiteDatabase sqLiteDatabase) {
            flag =
database.deleteFavorite(sqLiteDatabase, id);
         }
      });
      return
flag;
   }
  
   /**
    * 修改书签
    * @param id   修改的书签ID
    * @param name 修改后的书签名
    * @param url  修改后的书签地址
    * */
   public
boolean
modifyFavorite(final String id,final String name,
final String url) {
      flag = false;
      this.database.transactionAround(false,new CallBack()
{
        
         @Override
         public
void
doSomething(SQLiteDatabase sqLiteDatabase) {
            flag =
database.modifyFavorite(sqLiteDatabase, id, name, url);
         }
      });
      return
flag;
   }
  
   /**
    * 获取所有书签
    * @return   HashMap<String, String>
    * */
   public HashMap<String, String> getAllFavorites() {
      resultMap = new HashMap<String, String>();
      this.database.transactionAround(true,new CallBack()
{
        
         @Override
         public
void
doSomething(SQLiteDatabase sqLiteDatabase) {
            resultMap =
database.getAllFavorites(sqLiteDatabase);
         }
      });
      return
resultMap;
   }
}

代码片段10.2.4  书签事务管理
 

经过这些操作,我们就可以很容的发现我们的书签管理基本完成。不过,现在只能够添加事务,而不能够查看。现在我们可以来添加一个书签试试。

点击星星按钮:



图10.2.2    控制栏信息
 

可以看到我们这里已经成功添加。

 

现在咱们开始添加一个查看书签的View界面。因为TabActivity的界面不怎么好弄,所以,打算以FrameLayout的界面来进行界面的切换。

       

<?xmlversion="1.0"encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/favoritesAndHisotry"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/white"
    >
 
    <LinearLayout
       android:id="@+id/favoritesAndHisotry_button"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:background="@android:color/holo_blue_light"
       android:orientation="horizontal">
 
        <TextView
           android:id="@+id/favorites"
           android:layout_width="0dp"
           android:layout_height="match_parent"
           android:layout_margin="15dp"
           android:layout_weight="0.5"
           android:gravity="center"
           android:text="@string/favorite"
           android:textColor="@android:color/white"
           android:textSize="20sp"/>
 
        <TextView
           android:id="@+id/history"
           android:layout_width="0dp"
           android:layout_height="match_parent"
           android:layout_margin="15dp"
           android:layout_weight="0.5"
           android:gravity="center"
           android:text="@string/hisotry"
           android:textColor="@android:color/white"
           android:textSize="20sp"/>
    </LinearLayout>
 
    <FrameLayout
       android:id="@+id/favoritesAndHisotry_content"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:layout_below="@id/favoritesAndHisotry_button">
 
        <ListView
           android:id="@+id/favoritesAndHisotry_content_favorite"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:divider="#E2E2E2"
           android:dividerHeight="1dp">
        </ListView>
 
        <ListView
           android:id="@+id/favoritesAndHisotry_content_history"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:divider="#E2E2E2"
           android:dividerHeight="1dp"
           android:visibility="gone">
        </ListView>
    </FrameLayout>
 
</RelativeLayout>

代码片段10.2.5  收藏界面xml
       
注意,因为为了之后的历史功能的方便,我在这里也将历史的功能界面加了进去。但是功能现在不实现。

注意我修改了ListView的分割线效果,将他的颜色修改为了“E2E2E2”,高度为2dp。两个ListView一个隐藏,一个显示,为了进行历史和收藏的切换。

现在我们可以看看它的预览效果:

 



图10.2.3    收藏界面效果图
 

因为是新建立的Acitivity,我们需要在主配置文件中添加注册信息。

 

<activity
           android:name="com.example.androidstudy_web.FavAndHisActivity"
           android:theme="@android:style/Theme.NoTitleBar"
           android:label="@string/app_name"
           ></activity>

代码片段10.2.6  注册信息
 

现在定义一个单项的布局:

 

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="5dp"
    android:orientation="vertical">
   
    <TextView
       android:id="@+id/item_id"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:visibility="gone"
       />
    <TextView
       android:id="@+id/item_name"
       android:layout_width="match_parent"
       android:layout_height="20dp"
       android:textColor="@android:color/black"
       android:textSize="16sp"
       android:layout_marginLeft="15dp"
       android:layout_marginTop="5dp"
       />
    <TextView
       android:id="@+id/item_url"
       android:layout_width="match_parent"
       android:layout_height="18dp"
       android:textColor="#E2E2E2"
       android:textSize="13sp"
       android:layout_marginLeft="15dp"
       android:layout_marginBottom="5dp"
       />
 
</LinearLayout>

代码片段10.2.7  ListView单项item的布局
 

这个因为看不出来具体的布局预览,所以也就不放上去了。

我们必须传入一个id的值,用来更好的进行查询或者排序。

 

现在显示也已经完成了,我们可以来看看现在的显示效果。

 



图10.2.4    具体机子的运行效果
 

可以看到,我们从数据库中很容易的查询到了所需要的。

好了,现在我们可以看下,该如何实现上述的显示效果了:

 

/**
    * 初始化ListView中的数据
    * */
   @SuppressWarnings("deprecation")
   private
void
initData(Bundle savedInstanceState) {
      //获取书签管理
      this.favoritesManager =new FavoritesManager(this);
      this.favoritesCursor =this.favoritesManager.getAllFavorites();
      this.favorietesAdapter =new
SimpleCursorAdapter(getApplicationContext(),
            R.layout.list_item,this.favoritesCursor,
            new String[]{"_id","name","url"},
            new
int
[]{R.id.item_id, R.id.item_name,R.id.item_url});
      this.favoritesContent.setAdapter(this.favorietesAdapter);
   }

代码片段10.2.8  数据ListView的加载
 

这样,很容易就加载了数据,不过需要注意的是,Cursor的关闭,虽然Android操作系统有时候也会帮助关闭,不过它仍旧建议我们手动关闭。

       

@Override
   protected
void
onDestroy() {
      if (this.favoritesCursor !=null) {   

         this.favoritesCursor.close();   
       }
      super.onDestroy();
   }

代码片段10.2.9  关闭Cursor
 

至于如何关闭Cursor,上述的代码就是过程,只需要在关闭这个Activity的过程中关闭cursor就可以了,否则可能会出现cursor已关闭的错误。

 

好了,展示跟添加的操作已经完成了,接下来就是书签的修改和删除的操作了。至于像UC中的同步之类的,这个就不涉及了。

 

最开始的自然还是界面了,这个是毋庸置疑的。我选择了popupwindow作为弹出菜单,每次长按ListView中的单个条目,都会跳出一个popupwindow,这个弹窗拥有两个操作,一个是修改,一个是删除,每次点击的时候都会

 

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="5dp"
    android:orientation="vertical">
   
    <TextView
       android:id="@+id/item_longclicked_modifyFavorites"
       android:layout_width="match_parent"
       android:layout_height="20dp"
       android:textColor="@android:color/white"
       android:textSize="16sp"
       android:text="@string/modifyfavorites"
       android:layout_marginLeft="15dp"
       android:layout_marginTop="20dp"
       android:layout_marginBottom="5dp"
       />
   
    <TextView
       android:id="@+id/item_longclicked_deleteFavorites"
       android:layout_width="match_parent"
       android:layout_height="20dp"
       android:textColor="@android:color/white"
       android:textSize="16sp"
       android:text="@string/deletefavorites"
       android:layout_marginLeft="15dp"
       android:layout_marginTop="20dp"
       android:layout_marginBottom="5dp"
       />
 
</LinearLayout>

代码片段10.2.10 弹出popupwindow的布局
 

这个界面的预览我们可以看一下:

       



图10.2.5    弹出popupwindow的预览
 

 

 

或许会感到不对劲,这些都没什么关系,这个只是大体的布局,并不设置背景,因为这里如果直接设置背景,那么在实际过程中很难实现背景的圆角效果。我用的是java中设置。

 

首先,要设置圆角效果,先要设置圆角的背景:

       

<?xmlversion="1.0"encoding="utf-8"?>
<layer-listxmlns:android="http://schemas.android.com/apk/res/android">
 
    <item>
        <shapeandroid:shape="rectangle">
            <solidandroid:color="#504E5A"/>
 
            <corners
                android:bottomLeftRadius="5dp"
                android:bottomRightRadius="5dp"
                android:topLeftRadius="5dp"
                android:topRightRadius="5dp"/>
        </shape>
    </item>
 
</layer-list>

代码片段10.2.11 圆角背景
 

好了,基础工作已经做完了,那么接下来就是实现长按的事件了:

       

/**
 * 长按单项事件
 * 覆盖如下方法
 * 1. onItemLongClick
 * */
private
class
ListViewOnItemLongListener implements OnItemLongClickListener{
 
@Override
public
boolean
onItemLongClick(AdapterView<?> parent, View view,
int
position, long id) {
   Log.d(DEG_TAG,"long itemcliced");
         if(parent.getId()==R.id.favoritesAndHisotry_content_favorite){
ItemLongClickedPopWindowitemLongClickedPopWindow = new ItemLongClickedPopWindow(FavAndHisActivity.this, 200, 200);
         itemLongClickedPopWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.favandhis_activity));
            itemLongClickedPopWindow.showAsDropDown(view,view.getWidth()/2, -view.getHeight()/2);
         }else
if
(parent.getId()==R.id.favoritesAndHisotry_content_history){
           
         }
         return
false
;
      }
     
   }

代码片段10.2.12 长按事件的实现
 

注意这里的最后setBackgroundDrawable,这个就是设置背景圆角,好了,这样我们可以看看效果了,为了可以看出是不同条目,跳出的不同位置,我截图两张图片:

 





图10.2.6    弹出的不同情况
       
       
       
        开始完善功能,第一个要做的就是修改书签。
    修改书签就要弹出一个修改窗口,这里我是用的是AlertDialog的重新构建的方法。
   

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="5dp"
    android:background="@android:color/white"
    android:orientation="vertical">
   
    <LinearLayout
       android:id="@+id/dialog_name"
       android:layout_width="match_parent"
       android:layout_height="30dp"
       android:orientation="horizontal"
       android:layout_marginTop="30dp"
       android:layout_marginLeft="10dp"
       android:layout_marginRight="10dp"
       android:background="@drawable/dialog_back"
       >
 
        <TextView
           android:id="@+id/dialog_name_title"
           android:layout_width="50dp"
           android:layout_height="match_parent"
           android:gravity="center"
           android:textSize="15sp"
           android:text="@string/name"
           android:layout_marginLeft="5dp"
           android:layout_marginTop="5dp"
           android:layout_marginBottom="5dp"
           />
 
        <EditText
           android:id="@+id/dialog_name_input"
           android:layout_width="match_parent"
            android:layout_height="match_parent"
           android:hint="@string/blank"
           android:layout_marginRight="5dp"
           android:layout_marginTop="5dp"
           android:layout_marginBottom="5dp"
           android:background="@null"
           />
    </LinearLayout>
   
    <LinearLayout
       android:id="@+id/dialog_url"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="horizontal"
       android:layout_marginLeft="10dp"
       android:layout_marginRight="10dp"
       android:layout_marginTop="20dp"
       android:layout_marginBottom="30dp"
       android:background="@drawable/dialog_back"
       >
       
        <TextView
           android:id="@+id/dialog_url_title"
           android:layout_width="50dp"
           android:layout_height="match_parent"
           android:gravity="center"
           android:textSize="15sp"
           android:text="@string/url"
           android:layout_marginLeft="5dp"
           android:layout_marginTop="5dp"
           android:layout_marginBottom="5dp"
           />
 
        <EditText
           android:id="@+id/dialog_url_input"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:hint="@string/blank"
           android:layout_marginRight="5dp"
           android:layout_marginTop="5dp"
           android:layout_marginBottom="5dp"
           android:inputType="textUri"
            android:background="@null"
           />
    </LinearLayout>
   
</LinearLayout>

代码片段10.2.13 对话框布局
   
   
    这里我分成两个文本域,我们可以看下显示效果:



图10.2.7    对话框布局预览
   
    我们将长按事件修改如下:
   

/**
    * 长按单项事件
    * 覆盖如下方法
    * 1. onItemLongClick
    * */
   private
class
ListViewOnItemLongListener implements OnItemLongClickListener{
 
      @Override
      public
boolean
onItemLongClick(AdapterView<?> parent, View view,
            int position,long id) {
         Log.d(DEG_TAG,"long itemcliced");
         if(parent.getId()==R.id.favoritesAndHisotry_content_favorite){
            itemLongClickedPopWindow =new ItemLongClickedPopWindow(FavAndHisActivity.this, 200, 200);
         itemLongClickedPopWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.favandhis_activity));
            itemLongClickedPopWindow.showAsDropDown(view, view.getWidth()/2, -view.getHeight()/2);
            TextView modifyFavorite = (TextView)
itemLongClickedPopWindow.getView(R.id.item_longclicked_modifyFavorites);
            TextView deleteFavorite = (TextView)
itemLongClickedPopWindow.getView(R.id.item_longclicked_deleteFavorites);
            ItemClickedListener itemClickedListener = newItemClickedListener(view);
            modifyFavorite.setOnClickListener(itemClickedListener);
            deleteFavorite.setOnClickListener(itemClickedListener);
         }else
if
(parent.getId()==R.id.favoritesAndHisotry_content_history){
           
         }
         return
false
;
      }
     
   }

代码片段10.2.14 长按事件修改
   
    注意他增加了一个popupwindow的组件寻找,通过触发两个TextView来进行增加删除操作。
    而需要注意的是我们需要构建一个实现了OnClickedListener的类,用来处理传递过来的事件,而且因为需要用到一些ListView条目的值关系,所以必须将条目的view传递给事件处理类。
   
    下面是事件处理类的具体实现
   

/**
    * popupwindow按钮事件处理类
    * @param view 传入的ListView条目
    *     用来获取其中的id、name、url这三个值
    * 覆盖如下方法:
    * 1. onClick
    * */
   private
class
ItemClickedListener implements OnClickListener{
     
      private Stringitem_id;
      private Stringitem_name;
      private Stringitem_url;
     
      public ItemClickedListener(View item){
         this.item_id = ((TextView) item.findViewById(R.id.item_id)).getText().toString();
         this.item_name = ((TextView) item.findViewById(R.id.item_name)).getText().toString();
         this.item_url = ((TextView) item.findViewById(R.id.item_url)).getText().toString();
      }
 
      @Override
      public
void
onClick(View view) {
         //取消弹窗
         itemLongClickedPopWindow.dismiss();
         if(view.getId()==R.id.item_longclicked_modifyFavorites){
            //弹出修改窗口
            LayoutInflater modifyFavoritesInflater = LayoutInflater.from(FavAndHisActivity.this);
            View modifyFavoritesView =modifyFavoritesInflater.inflate(R.layout.dialog_modify,null);
            final TextView item_name_input = (TextView)modifyFavoritesView.findViewById(R.id.dialog_name_input);
            final TextView item_url_input = (TextView)modifyFavoritesView.findViewById(R.id.dialog_url_input);
            item_name_input.setText(item_name);
            item_url_input.setText(item_url);
            new AlertDialog.Builder(FavAndHisActivity.this)
                .setTitle("编辑书签")
                .setView(modifyFavoritesView)
                .setPositiveButton("确定",new DialogInterface.OnClickListener() {
                  
                   @Override
                  publicvoidonClick(DialogInterface dialog,
int which) {
                      Log.d(DEG_TAG,"id:"+item_id+",name:"+item_name+",url:"+item_url);
                      if(favoritesManager.modifyFavorite(item_id, item_name_input.getText().toString(),
                            item_url_input.getText().toString())){
                         Toast.makeText(FavAndHisActivity.this,"修改成功", Gravity.BOTTOM).show();
                         initData();
                         favoritesContent.invalidate();
                      }else{
                         Toast.makeText(FavAndHisActivity.this,"修改失败", Gravity.BOTTOM).show();
                      }
                   }
                  
                }).setNegativeButton("取消",null)
                .create()
                .show();
         }else
if
(view.getId()==R.id.item_longclicked_deleteFavorites){
            new AlertDialog.Builder(FavAndHisActivity.this)
                .setTitle("删除书签")
                .setMessage("是否要删除\""+item_name+"\"这个书签?")
                .setPositiveButton("删除",new DialogInterface.OnClickListener() {
                  
                   @Override
                   publicvoid onClick(DialogInterface dialog,
int which) {
                      if(favoritesManager.deleteFavorite(item_id)){
                         //删除成功
                         Toast.makeText(FavAndHisActivity.this,"删除成功", Gravity.BOTTOM).show();
                         initData();
                         favoritesContent.invalidate();
                      }else{
                         Toast.makeText(FavAndHisActivity.this,"删除失败", Gravity.BOTTOM).show();
                      }
                   }
                })
                .setNegativeButton("取消",null)
                .create()
                .show();
         }
           
      }
     
   }

代码片段10.2.15 popupwindow的按钮处理事件的具体实现
   
    可以看到我这里通过传递过来的ListView的条目View获取到三个量的TextView从而得到三个量的具体值。而取得了这三个值,那么就可以通过书签的事务管理类来进行相关的事务操作。
   
    书签的功能已经完成。

8.26
    补充:并未添加书签点击载入的功能
   
因为需要点击返回一个字符串的URL值,所以需要使用startActivityForResult的函数。改动如下:
       

startActivityForResult(new Intent(MainActivity.this,FavAndHisActivity.class),0);

代码片段10.2.15 开启activity修改
   
    注意,第二个参数为一个请求码,用来区分返回结果。并且需要复写onActivtiyResult函数:
   

@Override
protected
void
onActivityResult(int requestCode,
int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      switch(resultCode){
      case 0:
         webHolder.loadUrl(data.getStringExtra("url"));
      }
   }

代码片段10.2.16 返回结果处理
   
    这种返回处理其实类似于函数的回调功能。这里可以根据请求码结果码来区分进行相应的处理,我们这里比较简单,所以不管请求码还是结果码都为0,处理的操作就是将返回过来的url值进行webView的加载处理。
    好了,父Actvitiy已经处理完毕,那么现在可以进行子Activity的处理,这个处理其实就是在适当的时候传入返回结果就行了。
   

/**
    * ListView单击单项事件
    * 覆盖如下方法
    * 1. onClick
    * */
   private
class
ListViewOnItemClickedListener implementsOnItemClickListener{
 
      @Override
      public
void
onItemClick(AdapterView<?> arg0, View arg1, int arg2,
            long arg3) {
         if(arg0.getId()==R.id.favoritesAndHisotry_content_favorite){
            Intent intent = new Intent();
            intent.putExtra("url", ((TextView) arg1.findViewById(R.id.item_url)).getText().toString());
            setResult(0, intent);
            finish();
         }
      }
     
   }

代码片段10.2.17 实现ListView的单项单击方法
   
    注意,因为我们是通过单击ListView的条目来实现的,所以在单击的同时,将需要返回的url的值设置到result中,并且调用finish。
    这里还需要特别注意的是,我们虽然在onDestory的方法中关闭了Cursor,但是如果通过finish来调用返回的话,那么实际上Cursor并没有关闭,所以,我们还需要重写finish的方法:

@Override
   public
void
finish() {
      if (this.favoritesCursor !=
null) {   
         this.favoritesCursor.close();   

       }
      super.finish();
   }

代码片段10.2.18 finish方法覆写
   
    这样的话,那么就没问题了。当我们单击的时候,书签会返回给WebView载入URL。
   
    至此,补充完成。

    源代码:
   
AndroidStudy_web_V2.0_bydddd牛仔

    注意:转载请注明出处
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐