Сбой при перетаскивании изображения в Android на ICS (4.0.3) - PullRequest
1 голос
/ 29 марта 2012

То, что делает мое приложение, довольно просто:

Отображает миниатюрные изображения всех изображений на SD-карте в GridView. и значок в углу этих миниатюр, чтобы пользователь мог коснуться его, чтобы начать перетаскивая тень изображения.

Эта тень может быть отброшена на представлениях, которые были установлены слушателем перетаскивания. Когда это происходит, новое намерение будет вызываться с URI пути к файлу изображения в качестве дополнительного для новое намерение Пока все хорошо.

Проблема возникает, когда я начинаю отбрасывать тень на виды, у которых нет перетащите слушателя, в конечном итоге замораживая экран и сбой мобильного устройства!

Все, что я получаю в трассировке стека, это:

03-29 14:24:14.803: I/ViewRootImpl(2496): Reporting drop result: false
03-29 14:24:14.803: W/WindowManager(274): Drag is in progress but there is no drag window handle.
03-29 14:24:15.062: I/ViewRootImpl(2496): Reporting drop result: false
03-29 14:24:15.062: W/WindowManager(274): Drag is in progress but there is no drag window handle.
03-29 14:24:15.294: I/ViewRootImpl(2496): Reporting drop result: false
03-29 14:25:06.972: I/Process(274): Sending signal. PID: 274 SIG: 3
03-29 14:25:06.972: I/dalvikvm(274): threadid=3: reacting to signal 3
03-29 14:25:07.092: I/dalvikvm(274): Wrote stack traces to '/data/anr/traces.txt'
03-29 14:25:10.012: W/ActivityManager(274): Timeout of broadcast BroadcastRecord{2c09ce28 android.intent.action.TIME_TICK} - receiver=android.app.LoadedApk$ReceiverDispatcher$InnerReceiver@2bf0c4e8, started 10009ms ago
03-29 14:25:10.012: W/ActivityManager(274): Receiver during timeout: BroadcastFilter{2bf0cd08 ReceiverList{2bf0c660 274 system/1000 local:2bf0c4e8}}
03-29 14:25:20.022: W/ActivityManager(274): Timeout of broadcast BroadcastRecord{2c09ce28 android.intent.action.TIME_TICK} - receiver=android.app.LoadedApk$ReceiverDispatcher$InnerReceiver@2bef04e8, started 10008ms ago
03-29 14:25:20.022: W/ActivityManager(274): Receiver during timeout: BroadcastFilter{2bef0760 ReceiverList{2bef06e8 274 system/1000 local:2bef04e8}}
03-29 14:25:37.092: W/Watchdog(274): WATCHDOG PROBLEM IN SYSTEM SERVER: com.android.server.wm.WindowManagerService
03-29 14:25:37.102: I/Process(274): Sending signal. PID: 274 SIG: 3
03-29 14:25:37.102: I/dalvikvm(274): threadid=3: reacting to signal 3
03-29 14:25:37.182: I/dalvikvm(274): Wrote stack traces to '/data/anr/traces.txt'
03-29 14:25:37.192: I/Process(274): Sending signal. PID: 475 SIG: 3
03-29 14:25:37.192: I/dalvikvm(475): threadid=3: reacting to signal 3
03-29 14:25:37.202: I/dalvikvm(475): Wrote stack traces to '/data/anr/traces.txt'
03-29 14:25:39.204: I/Watchdog_N(274): dumpKernelStacks
03-29 14:25:39.492: I/CrashMonitor(1186): CrashMonitorService: invokeService: android.intent.action.DROPBOX_ENTRY_ADDED
03-29 14:25:39.492: W/Watchdog(274): *** WATCHDOG KILLING THE SYSTEM: com.android.server.wm.WindowManagerService

Мой класс адаптера (где я выполняю метод view.startDrag ()):

public class ImageCursorAdapter extends CursorAdapter {

    private LayoutInflater mInflater;
    private final static int mImageColumnID = 0;
    private Options mOptions = new Options();;
    private Cursor mCursor;

    public ImageCursorAdapter(Context context, Cursor c) {
        super(context, c);

        mInflater = LayoutInflater.from(context);
        mOptions.inSampleSize = 4;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        mCursor = cursor;
        ViewHolder holder = (ViewHolder) view.getTag();
        ImageThumbnailLoader imageLoader = new ImageThumbnailLoader(
            holder.thumbImg, cursor.getLong(mImageColumnID),
            context.getContentResolver(), false);
        imageLoader.execute();
//      holder.thumbImg.setImageBitmap(MediaStore.Images.Thumbnails.getThumbnail(
//                  context.getContentResolver(), cursor.getLong(mColumnID),
//                  MediaStore.Images.Thumbnails.MICRO_KIND, mOptions));
        holder.dragImg.setTag(holder.thumbImg);
        holder.dragImg.setId(cursor.getPosition());
        holder.dragImg.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();
                if (action == MotionEvent.ACTION_DOWN) {
                    mCursor.moveToPosition(v.getId());
                    int dataColumn = mCursor.getColumnIndex(MediaStore.Images.Media.DATA);
                    ClipData dragData = ClipData.newPlainText("filename",
                        mCursor.getString(dataColumn));
                    DragShadowBuilder shadow = new DragShadowBuilder((View) v.getTag());
                    return v.startDrag(dragData, shadow, null, 0);
                }
                return false;
            }
        });
        Log.i("Prototype", "bindView : " + cursor.getPosition());
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        Log.i("Prototype", "newView : " + cursor.getPosition());
        View view = mInflater.inflate(R.layout.grid_item, null);
        ViewHolder holder = new ViewHolder(view);
        view.setTag(holder);
        return view;
    }


    private static class ViewHolder {
        ImageView thumbImg, dragImg;

        ViewHolder(View base) {
            thumbImg = (ImageView) base.findViewById(R.id.thumbImage);
            dragImg = (ImageView) base.findViewById(R.id.dragImage);
        }
    }

}

Есть какие-нибудь идеи / подсказки о том, что здесь происходит? Я был бы очень признателен за это.

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 05 сентября 2012

Я столкнулся с аналогичной проблемой в том, что я не хотел, чтобы макет принимал действие удаления.

Прикрепите прослушиватель перетаскивания к вашему виду через setOnDragListener.

view.setOnDragListener (new MyDragListener ());

Проверьте, является ли целевое представление в событии onDrag требуемым представлением. Если условие ложно, поместите желаемый код там.

class MyDragListener implements OnDragListener {

@Override
public boolean onDrag(View v, DragEvent event) {

  switch (event.getAction()) {
  case case DragEvent.ACTION_DROP:
         //check whether it has not been dropped onto your view
          if(v!=view)
              //your code here
}
1 голос
/ 17 мая 2012

если у вас есть инструкция переключения регистра в вашем методе onDrag (View v, DragEvent), то вы должны добавить туда регистр DragEvent.ACTION_DRAG_LOCATION.Там вы можете определить, что должно произойти, если ваш значок / изображение будет помещено в поле без перетаскивания.

Вот пример:

public class MyDragListener implements OnDragListener {

  @Override
  public boolean onDrag(View v, DragEvent event) {
    int action = event.getAction();
    switch ( action ) {
    case DragEvent.ACTION_DRAG_STARTED:
        break;
    case DragEvent.ACTION_DRAG_ENTERED:
        break;
    case DragEvent.ACTION_DRAG_EXITED:
        break;
    case DragEvent.ACTION_DROP:
        View view = (View) event.getLocalState();
        ViewGroup owner = (ViewGroup) view.getParent();
        owner.removeView(view);
        RelativeLayout container = (RelativeLayout) v;
        container.addView(view);
        view.setVisibility(View.VISIBLE);
        break;
    case DragEvent.ACTION_DRAG_ENDED:
                    break;
    case DragEvent.ACTION_DRAG_LOCATION:
        view.setVisibility(View.VISIBLE);
        break;
    }
  }

}
...