Android拖放小工具

时间:2014-07-07 15:21:26

标签: android drag-and-drop android-widget android-launcher

我目前正在开发一个简单的Android自定义启动器,我在操作小部件方面遇到了问题。我正在尝试拖放用户选择的小部件。 这是我的代码

public class FragmentBlue extends Fragment implements OnLongClickListener 
{
static final String TAG = "FragmentBlue";
private static final String IMAGEVIEW_TAG = "The Android Logo";
public static final int RESULT_OK = -1;
public static final int CODE_PICK_APPWIDGET = 1;
public static final int RESULT_CANCELED = 0;

Object DragShadowBuilder;

AppWidgetManager mAppWidgetManager;
LauncherAppWidgetHost mAppWidgetHost;   
ViewGroup mainlayout; 
int numwidgets;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_blue, container, false);    
    mainlayout = (ViewGroup) view.findViewById(R.id.home_view);    
    mainlayout.setOnLongClickListener(this);

    mAppWidgetManager = AppWidgetManager.getInstance(getActivity());
    mAppWidgetHost = new LauncherAppWidgetHost(getActivity(), R.id.APPWIDGET_HOST_ID);
    return view;
}

/**
 * Launches the menu to select the widget. The selected widget will be on
 * the result of the activity.
 */
void selectWidget() {       
    int appWidgetId = this.mAppWidgetHost.allocateAppWidgetId();
    Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
    pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    addEmptyData(pickIntent);
    startActivityForResult(pickIntent, CODE_PICK_APPWIDGET);
}    

void addEmptyData(Intent pickIntent) {
    ArrayList<AppWidgetProviderInfo> customInfo = new ArrayList<AppWidgetProviderInfo>();
    pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo);
    ArrayList<Bundle> customExtras = new ArrayList<Bundle>();
    pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras);
}

/**
 * If the user has selected an widget, the result will be in the 'data' when
 * this function is called.
 */
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == CODE_PICK_APPWIDGET) {
            configureWidget(data);
        } else if (requestCode == R.id.REQUEST_CREATE_APPWIDGET) {
            createWidget(data);
        }
    } else if (resultCode == RESULT_CANCELED && data != null) {
        int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
        if (appWidgetId != -1) {
            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
        }
    }
}

/**
 * Checks if the widget needs any configuration. If it needs, launches the
 * configuration activity.
 */
private void configureWidget(Intent data) {
    Bundle extras = data.getExtras();
    int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
    AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
    if (appWidgetInfo.configure != null) {
        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
        intent.setComponent(appWidgetInfo.configure);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        startActivityForResult(intent, R.id.REQUEST_CREATE_APPWIDGET);
    } else {
        createWidget(data);
    }
}

/**
 * Creates the widget and adds to our view layout.
 */
public void createWidget(Intent data) {
    Bundle extras = data.getExtras();
    int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
    AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);

    LauncherAppWidgetHostView hostView = (LauncherAppWidgetHostView) mAppWidgetHost.createView(getActivity(), appWidgetId, appWidgetInfo);
    hostView.setAppWidget(appWidgetId, appWidgetInfo);
    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(mainlayout.getWidth()/3, mainlayout.getHeight()/3);
    lp.leftMargin = numwidgets * (mainlayout.getWidth()/3);

    hostView.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                ClipData data = ClipData.newPlainText("", "");
                DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
                view.startDrag(data, shadowBuilder, view, 0);
                view.setVisibility(View.INVISIBLE);
                return true;
              } else {
                return false;
              }

        }
    });
    hostView.setOnDragListener(new OnDragListener() {
         Drawable enterShape = getResources().getDrawable(R.drawable.shape_droptarget);
            Drawable normalShape = getResources().getDrawable(R.drawable.shape);
        @Override
        public boolean onDrag(View v, DragEvent event) {
             int action = event.getAction();
              switch (event.getAction()) {
              case DragEvent.ACTION_DRAG_STARTED:
                // do nothing
                break;
              case DragEvent.ACTION_DRAG_ENTERED:
                v.setBackgroundDrawable(enterShape);
                break;
              case DragEvent.ACTION_DRAG_EXITED:
                v.setBackgroundDrawable(normalShape);
                break;
              case DragEvent.ACTION_DROP:
                // Dropped, reassign View to ViewGroup
                View view = (View) event.getLocalState();
                ViewGroup owner = (ViewGroup) view.getParent();
                owner.removeView(view);
                GridLayout container = (GridLayout) v;
                container.addView(view);
                view.setVisibility(View.VISIBLE);
                break;
              case DragEvent.ACTION_DRAG_ENDED:
                v.setBackgroundDrawable(normalShape);
              default:
                break;
              }
              return true;
        }
    });


    mainlayout.addView(hostView,lp);
    numwidgets ++;
}

我使用的xml就是这个:

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"   
    android:columnWidth="300dp"
    android:orientation="vertical"
    android:stretchMode="columnWidth"   
    android:id="@+id/home_view"
    >
    <android.widget.Space
        android:id="@+id/space1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</GridLayout>

问题是当我开始拖动小部件时。我可以拖动它,但当我尝试删除它时,它会消失。我想我的布局原因,但我找不到任何解决方案...... 我知道我不完全可以理解,但我是Android世界的新手。非常感谢!!!

2 个答案:

答案 0 :(得分:0)

小部件不应该实现DragListener,而是应该放置它们的位置。

试试吧

mainlayout = (ViewGroup) view.findViewById(R.id.home_view);    
mainlayout.setOnDragListener(new OnDragListener() {
         Drawable enterShape = getResources().getDrawable(R.drawable.shape_droptarget);
            Drawable normalShape = getResources().getDrawable(R.drawable.shape);
        @Override
        public boolean onDrag(View v, DragEvent event) {
             int action = event.getAction();
              switch (event.getAction()) {
              case DragEvent.ACTION_DRAG_STARTED:
                // do nothing
                break;
              case DragEvent.ACTION_DRAG_ENTERED:
                v.setBackgroundDrawable(enterShape);
                break;
              case DragEvent.ACTION_DRAG_EXITED:
                v.setBackgroundDrawable(normalShape);
                break;
              case DragEvent.ACTION_DROP:
                // Dropped, reassign View to ViewGroup
                View view = (View) event.getLocalState();
                ViewGroup owner = (ViewGroup) view.getParent();
                owner.removeView(view);
                GridLayout container = (GridLayout) v;
                container.addView(view);
                view.setVisibility(View.VISIBLE);
                break;
              case DragEvent.ACTION_DRAG_ENDED:
                v.setBackgroundDrawable(normalShape);
              default:
                break;
              }
              return true;
        }
    });

答案 1 :(得分:0)

您必须将OnDragListener设置为要拖动的View,并设置为要放到的View