我想在浏览器中显示最近访问过的网址的屏幕截图,例如google chrome。
我能够获得相同的网址,标题和图标,但也希望显示最近访问过的网站的截图。请引导我完成此操作。
答案 0 :(得分:1)
与大多数其他视图一样,WebView可以将自己绘制到提供的Canvas上。页面加载后,我们可以使用此方法创建呈现页面的屏幕截图,并将其与网站的标题和图标一起添加到GridView。以下示例相当通用,因为我确定您要自定义它。
我已将此功能包装在Fragment中,而Fragment只需要对WebView的引用。在我的简单演示应用程序中,我在WebView的WebViewClient的addCurrentSite()
回调中调用了Fragment的onPageFinished()
方法,为每个访问过的新URL创建了一个屏幕截图。 Fragment类还提供了一个回调接口,Activity可以实现该回调接口来响应屏幕截图的点击。此外,长按屏幕截图会将其从列表中删除。
首先,WebShotFragment
类:
public class WebShotFragment extends Fragment {
private WebView webView;
private GridView grid;
private SiteMap<String, Site> sites = new SiteMap<String, Site>();
private SiteAdapter adapter;
public WebShotFragment() {}
public interface OnSiteSelectedListener {
public void onSiteSelected(String url);
}
private OnSiteSelectedListener listener;
public void setOnSiteSelectedListener(OnSiteSelectedListener listener) {
this.listener = listener;
}
public void registerWebView(WebView webView) {
this.webView = webView;
}
public void addCurrentSite() {
if (!sites.containsKey(webView.getUrl())) {
webView.postDelayed(new Runnable() {
@Override
public void run() {
Bitmap bmp = getWebshot();
sites.put(webView.getUrl(), new Site(webView.getTitle(), webView.getUrl(), webView.getFavicon(), bmp));
adapter.notifyDataSetChanged();
}
}, 1000);
}
}
private Bitmap getWebshot() {
Bitmap bmp = Bitmap.createBitmap(webView.getWidth(), webView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
webView.draw(canvas);
Bitmap res = Bitmap.createBitmap(200, 150, Bitmap.Config.ARGB_8888);
canvas = new Canvas(res);
canvas.drawBitmap(bmp,
new Rect(0, 0, bmp.getWidth(), bmp.getHeight()),
new Rect(0, 0, res.getWidth(), res.getHeight()),
new Paint());
return res;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
adapter = new SiteAdapter(activity, sites);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
grid = (GridView) inflater.inflate(R.layout.fragment_webshot, container, false);
grid.setAdapter(adapter);
grid.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (listener != null)
listener.onSiteSelected(sites.getValue(position).url);
}
});
grid.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
sites.remove(sites.getEntry(position).getKey());
adapter.notifyDataSetChanged();
return true;
}
});
return grid;
}
private class SiteAdapter extends BaseAdapter {
private LayoutInflater inflater;
private SiteMap<String, Site> sites;
public SiteAdapter(Context context, SiteMap<String, Site> sites) {
this.inflater = LayoutInflater.from(context);
this.sites = sites;
}
@Override
public int getCount() {
return sites.size();
}
@Override
public Object getItem(int position) {
return sites.getValue(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = inflater.inflate(R.layout.webshot, null);
Site s = (Site) getItem(position);
((ImageView) v.findViewById(R.id.icon)).setImageBitmap(s.icon);
((TextView) v.findViewById(R.id.title)).setText(s.title);
((ImageView) v.findViewById(R.id.shot)).setImageBitmap(s.webshot);
return v;
}
}
private class Site {
public String title, url;
public Bitmap icon, webshot;
public Site(String title, String url, Bitmap icon, Bitmap webshot) {
this.title = title;
this.url = url;
this.icon = icon;
this.webshot = webshot;
}
}
private class SiteMap<K, V> extends LinkedHashMap<K, V> {
public V getValue(int i) {
Map.Entry<K, V> entry = this.getEntry(i);
if (entry == null)
return null;
return entry.getValue();
}
public Map.Entry<K, V> getEntry(int i) {
if (i < 0)
throw new IllegalArgumentException("Index cannot be negative");
Set<Map.Entry<K,V>> entries = entrySet();
int j = 0;
for (Map.Entry<K, V> entry : entries)
if (j++ == i)
return entry;
return null;
}
}
}
此类使用两个布局文件。这里,GridView的fragment_webshot.xml
:
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:padding="10dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp" />
webshot.xml
项目:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#eeeeee"
android:padding="5dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity="center_vertical">
<ImageView android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:scaleType="fitXY" />
<Space
android:layout_width="10dp"
android:layout_height="match_parent" />
<TextView android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true" />
</LinearLayout>
<ImageView android:id="@+id/shot"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scaleType="fitXY" />
</LinearLayout>
活动中的设置很少。只需获取对WebView的引用,设置其WebViewClient,并将其注册到WebShotFragment。如上所述,我在每个addCurrentSite()
回调上执行Fragment onPageFinished()
方法只是为了演示;你可能想改变它。
public class MainActivity extends Activity
implements WebShotFragment.OnSiteSelectedListener {
...
WebView webView;
WebShotFragment webShotFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
webView = (WebView) findViewById(...);
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
return false;
}
public void onPageFinished(WebView webView, String url) {
webShotFragment.addCurrentSite();
}
});
webShotFragment = ... // Instantiate/initialize the Fragment
webShotFragment.setOnSiteSelectedListener(this);
webShotFragment.registerWebView(webView);
...
}
@Override
public void onSiteSelected(String url) {
webView.loadUrl(url);
}
}
示例应用的截图: