Android网络:开发浏览器(二)——功能完善之书签功能
经过上述的编写,基本的功能已经完成了,不过工具栏里面基本还是一片空白,只有一个刷新的功能,现在咱们就先完善这些功能(之前有朋友说来点图,那么这次我会截些图更好的来描述)。
既然是浏览器,怎么能没有书签的功能,为了操作方便,我就将添加的书签放在地址栏的旁边,我比较喜欢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
(getApplicationContext(),
SimpleCursorAdapter
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, intposition, 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牛仔
注意:转载请注明出处
Android网络:开发浏览器(二)——功能完善之书签功能的更多相关文章
- Android NFC开发(二)——Android世界里的NFC所具备的条件以及使用方法
Android NFC开发(二)--Android世界里的NFC所具备的条件以及使用方法 NFC的应用比较广泛,而且知识面也是比较广的,所以就多啰嗦了几句,我还还是得跟着官方文档:http://dev ...
- Android ROM开发(二)——ROM架构以及Updater-Script脚本分析,常见的Status错误解决办法
Android ROM开发(二)--ROM架构以及Updater-Script脚本分析,常见的Status错误解决办法 怪自己二了,写好的不小心弄没了,现在只好重新写一些了,上篇简单的配置了一下环境, ...
- IOS网络开发(二)
1 局域网群聊软件 1.1 问题 UDP协议将独立的数据包从一台计算机传输到另外一台计算机,但是并不保证接受方能够接收到该数据包,也不保证接收方所接收到的数据和发送方所发送的数据在内容和顺序上是完全一 ...
- Android NDK 开发(二) -- 从Hlello World学起【转】
转载请注明出处:http://blog.csdn.net/allen315410/article/details/41805719 上篇文章讲述了Android NDK开发的一些基本概念,以及NDK ...
- Android开发(二十八)——基础功能函数
/** * 判断事件是否在控件中 * * @param view * @param ev * @return * @see http://m.blog.csdn.net/blog/aygxylxk/8 ...
- 《精通android网络开发》--HTTP数据通信
No1: 例如:http://www.*****.com/china/index.htm 1)http:// 代表超文本传送协议,通知*****.com服务器显示web页,通常不用输入 2)www 代 ...
- android网络开发之测试机连接到服务器上面
1:本人使用Tomcat作为服务器软件,首先打开Tomcat.(可以在浏览器中输入http://www.127.0.0.1:8080/查看) 2:服务器后台使用Servelt开发,这里不再讲解. 3: ...
- Android网络开发实例(基于抓包实现的网络模拟登录,登出和强制登出)
学习Android有几个月了,最近喜欢上了网络编程,于是想通过Android写一些一个小程序用于连接外网.在这里非常感谢雪夜圣诞的支持,非常感谢,给我打开新的一扇门. 1.声明,本程序只能用于西南大学 ...
- Android网络开发
1. WebView用法 ①布局文件新建一个WebView,特别注意线性布局和控件的宽高都要匹配父控件 <LinearLayout xmlns:android="http://sche ...
随机推荐
- Codeforces Round #259 (Div. 1) A. Little Pony and Expected Maximum 数学公式结论找规律水题
A. Little Pony and Expected Maximum Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.c ...
- MySQL数据库基准压力测试工具之MySQLSlap使用实例
一.Mysqlslap介绍 mysqlslap是MySQL5.1之后自带的benchmark基准测试工具,类似Apache Bench负载产生工具,生成schema,装载数据,执行benckmark和 ...
- [Linux] Ubuntu 18 LTS netplan 网络配置
Ubuntu 18 LTS netplan 网络配置 今天装完 Ubuntu 18 LTS,配置网络时发现Ubuntu 18LTS ifupdown has been replaced by netp ...
- JetBrains 系列软件汉化包
原文地址:https://blog.csdn.net/pingfangx/article/details/78826145 JetBrains 系列软件汉化包 关键字: Android Studio ...
- java8函数式接口小例子
// Function<T, R> -T作为输入,返回的R作为输出 Function<String,String> function = (x) -> {System.o ...
- Shell下的通配符、特殊符号和文件描写叙述符
一:通配符 * 代表『 0 个到无穷多个』随意字符 演示样例:找出 /etc/ 底下以 cron 为开头的文件名称的文件 [root@instructor Desktop]# ls /etc/cron ...
- FreeCMS开发过程问题总结(持续更新中)
正在做freecms的二次开发,特对开发过程中遇到的问题及原因分析进行总结分享,共勉. 2014/4/25 错误提示:静态化处理失败,原因:Expression answerList is undef ...
- 15个具有高度影响力的Apache开源项目
自1999年创立以来,Apache软件基金会如今已成了众多重要的开源软件项目之家.其中成功的项目有Geronimo,有Tomcat,有Hadoop,有如今成了大数据王国关键车毂的分布式计算系统. 虽然 ...
- Asp.net FileUpload+Image制作头像效果
在Web开发中会经常使用到个人信息注册,而个人信息中通常需要自己的头像或者照片.今天主要介绍一下使用FileUpload+img控件上传照片. FileUpLoad控件使用介绍 FileUpLoad控 ...
- Git 学习(八)其他
Git 学习(八)其他 通过以上七章Git的学习,基本操作已差不多了,本章介绍一点落网之鱼: 包括如何忽略文件.配置别名.以及使用GitHub等. 当然,Git的强大远不是七章内容可概括的,之后可结 ...