我们有一个包含大量项目的GridView,以至于用户需要向下滚动才能看到它们。 GridView中的每个项目都由Textview和Webview组成,并附带了一些事件。
问题:对于首次创建活动时不可见的项目(您需要向下滚动查看的项目),不会触发OnItemLongClickListener。
相关代码:
活动 -
public class MyCoursesActivity extends ActivityBase implements ILoginListener, IUpdateListener, OnDragListener {
private ArrayList<Course> myCoursesList = new ArrayList<Course>();
private int draggedIndex = -1;
CoursesListAdapter coursesAdapter = new CoursesListAdapter(MyCoursesActivity.this, myCoursesList);
MyCourseAdapter mca = new MyCourseAdapter();
private void Load() throws ParseException
{
myCoursesList = mca.Load();
coursesAdapter = new CoursesListAdapter(MyCoursesActivity.this, myCoursesList);
final GridView gv = (GridView) findViewById(R.id.mycourses_Grid);
gv.setAdapter(coursesAdapter);
gv.setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView gridView, View view,
int position, long row) {
view = gridView.getChildAt(position);
ClipData.Item item = new ClipData.Item("");
ClipData clipData = new ClipData("",
new String[] { ClipDescription.MIMETYPE_TEXT_PLAIN }, item);
view.startDrag(clipData, new View.DragShadowBuilder(view), null, 0);
View trashCan = findViewById(R.id.trash_can);
trashCan.setVisibility(View.VISIBLE);
trashCan.setOnDragListener(MyCoursesActivity.this);
draggedIndex = position;
return true;
}
});
}
public boolean onDrag(View view, DragEvent dragEvent) {
switch (dragEvent.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
if (view.getId() == R.id.trash_can) {
view.animate().scaleX(1.0f);
view.animate().scaleY(1.0f);
return true;
} else
if (dragEvent.getClipDescription().hasMimeType(
ClipDescription.MIMETYPE_TEXT_PLAIN)) {
return true;
} else {
return false;
}
case DragEvent.ACTION_DRAG_ENTERED:
if (view.getId() == R.id.trash_can) {
view.animate().scaleX(1.5f);
view.animate().scaleY(1.5f);
}
return true;
case DragEvent.ACTION_DRAG_EXITED:
if (view.getId() == R.id.trash_can) {
view.animate().scaleX(1.0f);
view.animate().scaleY(1.0f);
}
view.invalidate();
return true;
case DragEvent.ACTION_DRAG_LOCATION:
return true;
case DragEvent.ACTION_DROP:
if (view.getId() == R.id.trash_can) {
//do stuff
}
coursesAdapter.notifyDataSetChanged();
case DragEvent.ACTION_DRAG_ENDED:
// Hide the trash can
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
findViewById(R.id.trash_can).setVisibility(View.INVISIBLE);
}
}, 1000l);
if (view.getId() == R.id.trash_can) {
view.animate().scaleX(1.0f);
view.animate().scaleY(1.0f);
} else {
view.setVisibility(View.VISIBLE);
}
// remove drag listeners
view.setOnDragListener(null);
return true;
}
return false;
}
}
GridView适配器 -
public class CoursesListAdapter extends BaseAdapter {
private Context context;
private ArrayList<Course> courses;
public CoursesListAdapter(Context context, ArrayList<Course> courses){
this.context = context;
this.courses = courses;
}
<@Override getCount etc.>
@Override
public View getView(int position, View convertView, ViewGroup parentView) {
final Course course = (Course) getItem(position);
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.course_view, parentView, false);
if(context instanceof OnDragListener){
convertView.setTag(course);
convertView.setOnDragListener((OnDragListener) context);
}
TextView title = (TextView) convertView.findViewById(R.id.courseview_titleTv);
title.setText(course.getTitle());
WebView wv = (WebView) convertView.findViewById(R.id.courseview_imageWv);
wv.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View arg0, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
Intent myIntent = new Intent(context, CourseDetailsActivity.class);
myIntent.putExtra("Course", course);
context.startActivity(myIntent);
return true;
}
return false;
}
});
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent myIntent = new Intent(context, CourseDetailsActivity.class);
myIntent.putExtra("Course", course);
context.startActivity(myIntent);
}
});
return convertView;
}
}
有什么想法吗?谢谢。
编辑: 尝试使用ImageViews而不是WebViews,似乎不再有事件的问题。我们尝试使用固定的drawable。我们试图让webview的实际内容在自己的项目中的ImageView中显示,以简化故障排除。这是迄今为止的代码。 ImageView不显示任何图像(例如谷歌涂鸦)
WebView到ImageView -
final WebView mWeb = (WebView) findViewById(R.id.webView1);
//final WebView mWeb = new WebView(this);
final ImageView imgView = (ImageView) findViewById(R.id.imageView1);
mWeb.setInitialScale(100);
mWeb.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView v, String url){
Picture picture = mWeb.capturePicture();
Bitmap bitmap = Bitmap.createBitmap(picture.getWidth(), picture.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas c =new Canvas(bitmap);
picture.draw(c);
imgView.setMinimumWidth(bitmap.getWidth());
imgView.setMinimumHeight(bitmap.getHeight());
imgView.setImageBitmap(bitmap);
imgView.setVisibility(View.VISIBLE);
}
});
mWeb.loadUrl("http://www.google.com");
答案 0 :(得分:0)
我就是这样做的,它对我有用:
package com.test.progress;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Picture;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WebView mWeb = (WebView) findViewById(R.id.webView1);
// final WebView mWeb = new WebView(this);
final ImageView imgView = (ImageView) findViewById(R.id.imageView1);
mWeb.setInitialScale(100);
mWeb.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView v, String url) {
v.postDelayed(new Runnable() {
@Override
public void run() {
Picture picture = mWeb.capturePicture();
Bitmap bitmap = Bitmap.createBitmap(picture.getWidth(),
picture.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas c = new Canvas(bitmap);
picture.draw(c);
imgView.setMinimumWidth(bitmap.getWidth());
imgView.setMinimumHeight(bitmap.getHeight());
imgView.setImageBitmap(bitmap);
imgView.setVisibility(View.VISIBLE);
}
}, 100);
}
});
mWeb.loadUrl("http://www.google.com");
}
}
xml layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/frage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<WebView
android:id="@+id/webView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
</LinearLayout>
不要忘记添加:
<uses-permission android:name="android.permission.INTERNET" />
更新1:
似乎WebView
必须对用户可见以捕捉图片,这是一个完美运作的愚蠢解决方案。
注意:永远不要将位图存储在内存中,就像我在下面的示例中所做的那样。有很好的库可用于缓存目的,使用它们。
package com.vj.test;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Picture;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
ArrayAdapter<Data> mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gv = (GridView) findViewById(R.id.gridView1);
final List<Data> data = new ArrayList<Data>();
try {
data.add(new Data(new URI("http://www.google.com")));
data.add(new Data(new URI("http://www.yahoo.com")));
data.add(new Data(new URI("http://www.facebook.com")));
data.add(new Data(new URI("http://www.google.com")));
data.add(new Data(new URI("http://www.google.com")));
data.add(new Data(new URI("http://www.google.com")));
} catch (Exception e) {
}
mAdapter = new ArrayAdapter<Data>(this, R.layout.cell, R.id.url, data) {
private Map<URI, Boolean> loadingUrls = new HashMap<URI, Boolean>();
private boolean loadingStarted = false;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(MainActivity.this)
.inflate(R.layout.cell, null);
}
Data d = getItem(position);
ImageView imageView = (ImageView) convertView
.findViewById(R.id.bitmap);
if (d.bm == null) {
convertView.findViewById(R.id.progress).setVisibility(
View.VISIBLE);
imageView.setImageBitmap(null);
loadBitmap(d);
} else {
imageView.setImageBitmap(d.bm);
convertView.findViewById(R.id.progress).setVisibility(
View.GONE);
}
TextView tv = (TextView) convertView.findViewById(R.id.url);
tv.setText(d.url.getHost() + "");
return convertView;
}
private void loadBitmap(final Data d) {
synchronized (loadingUrls) {
if (loadingUrls.containsKey(d.url)) {
return;
}
loadingUrls.put(d.url, false);
}
if (loadingStarted) {
return;
}
loadingStarted = true;
final WebView mWeb = (WebView) findViewById(R.id.laodingWebView);
mWeb.setDrawingCacheEnabled(true);
mWeb.setInitialScale(100);
mWeb.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView v, final String url) {
v.postDelayed(new Runnable() {
@Override
public void run() {
Picture picture = mWeb.capturePicture();
Bitmap bitmap = Bitmap.createBitmap(100, 100,
Bitmap.Config.ARGB_8888);
final Canvas c = new Canvas(bitmap);
picture.draw(c);
URI nextUrl = null;
// d.bm = bitmap;
synchronized (loadingUrls) {
loadingUrls.put((URI) mWeb.getTag(), true);
}
updateAllSimilar((URI) mWeb.getTag(), bitmap);
mAdapter.notifyDataSetChanged();
for (Entry<URI, Boolean> s : loadingUrls
.entrySet()) {
if (!s.getValue()) {
nextUrl = s.getKey();break;
}
}
if (nextUrl != null) {
loadNext(mWeb, nextUrl);
} else {
mWeb.setVisibility(View.GONE);
}
}
}, 50);
}
});
URI url = null;
for (Entry<URI, Boolean> s : loadingUrls.entrySet()) {
if (!s.getValue()) {
url = s.getKey();break;
}
}
if (url != null) {
loadNext(mWeb, url);
}
}
private void updateAllSimilar(URI url, Bitmap bm) {
synchronized (data) {
for (Data d : data) {
if (d.url.equals(url)) {
d.bm = bm;
}
}
}
}
private void loadNext(WebView mWeb, URI url) {
mWeb.loadUrl(url.toString());
mWeb.setTag(url);
}
};
gv.setAdapter(mAdapter);
}
static class Data {
Bitmap bm;// don't ever do this, Use cache libraries instead
URI url;
public Data(URI uri) {
this.url = uri;
}
}
}
activity_main.xml中
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<GridView
android:id="@+id/gridView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:numColumns="2" >
</GridView>
<WebView
android:id="@+id/laodingWebView"
android:layout_width="match_parent"
android:layout_height="1px" />
</LinearLayout>
cell.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/bitmap"
android:layout_width="match_parent"
android:layout_height="80dp"
android:scaleType="fitCenter" />
<TextView
android:id="@+id/url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:maxLines="1"
android:singleLine="true" />
</LinearLayout>
<ProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>