对于不可见的项目,Android GridView不会触发onLongItemTouchListener

时间:2013-07-08 09:04:31

标签: android gridview webview ontouchlistener onlongclicklistener


我们有一个包含大量项目的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");

1 个答案:

答案 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>