android - 拖放持久位置

标签 android android-fragments drag-and-drop android-relativelayout

我正在开发一个在相对布局中使用拖放 View 的项目。我有一个按钮,单击时会生成新的 ImageView 。该 ImageView 创建在屏幕的左上角,相对于父 View 为 (0,0)。然后我可以将 ImageView 拖放到我想要的任何位置。问题是:当我再次单击按钮以创建另一个 ImageView 时,所有 ImageView 都会移动到左上角。我是否应该使用不同的添加方法或某种方法来保持其他 ImageView 就位?所有代码都贴在下面。

代码:

MyFragment.java

package com.example.layouttest;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MyFragment extends Fragment {
    public static final String EXTRA_MESSAGE = "EXTRA_MESSAGE";
    public String text;
    static FragmentManager fragMan;

    public static final MyFragment newInstance(String message)
    {
        MyFragment f = new MyFragment();
        f.setRetainInstance(true);
        Bundle bdl = new Bundle(1);
        bdl.putString(EXTRA_MESSAGE, message);
        f.setArguments(bdl);
        return f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) {
        String message = getArguments().getString(EXTRA_MESSAGE);
        View v = inflater.inflate(R.layout.myfragment_layout, container, false);
        TextView messageTextView = (TextView)v.findViewById(R.id.textView);
        messageTextView.setText(message);
        text = message;
        return v;
    }
}

PageViewActivity.java

package com.example.layouttest;

import java.util.ArrayList;
import java.util.List;

import com.example.layouttest.R;

import android.content.ClipData;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.RelativeLayout;

public class PageViewActivity extends FragmentActivity {
    MyPageAdapter pageAdapter;
    FragmentManager fragMan;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_page_view);
        fragMan = getSupportFragmentManager();
        List<Fragment> fragments = getFragments();
        FragmentTransaction fragTrans = fragMan.beginTransaction();
        fragTrans.commit();
        pageAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
        ViewPager pager = (ViewPager)findViewById(R.id.viewpager);
        pager.setAdapter(pageAdapter);
        pager.setPageTransformer(true, new ZoomOutPageTransformer());
        pager.setCurrentItem(pageAdapter.cur);
    }

    public void click(View v){
        RelativeLayout layout = (RelativeLayout)v.getParent();
        ImageView image = new ImageView(this);
        image.setLayoutParams(new LayoutParams(80,80));
        image.setImageDrawable(getResources().getDrawable(R.drawable.shape));
        image.setOnTouchListener(new MyTouchListener());
        layout.setOnDragListener(new MyDragListener(layout));
        layout.addView(image);
    }

    private List<Fragment> getFragments(){
        List<Fragment> fList = new ArrayList<Fragment>();
        for(int i = 1; i <= 5;i++){
            MyFragment f = MyFragment.newInstance("Fragment " + i);
            fList.add(f);
        }
        return fList;
    }

    private class MyPageAdapter extends FragmentPagerAdapter {
        public List<Fragment> fragments;
        public int cur;

        public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
            super(fm);
            this.fragments = fragments;
            cur = fragments.size()/2;
        }
        @Override
        public Fragment getItem(int position) {
            return this.fragments.get(position);
        }

        @Override
        public int getCount() {
            return this.fragments.size();
        }
    }

    private class MyTouchListener implements OnTouchListener{

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

MyDragListener.java

package com.example.layouttest;

import android.util.Log;
import android.view.DragEvent;
import android.view.View;
import android.view.View.OnDragListener;
import android.widget.RelativeLayout;

public class MyDragListener implements OnDragListener{
    int x;
    int y;
    RelativeLayout layout;

    public MyDragListener(RelativeLayout l){
        layout = l;
    }

    @Override
    public boolean onDrag(View v, DragEvent event) {
        int action = event.getAction();
        View view = (View) event.getLocalState();
        RelativeLayout l = (RelativeLayout)view.getParent();
        if(!l.equals(layout))
            return false;
        if(action == DragEvent.ACTION_DRAG_LOCATION){
            x = (int)event.getX();
            y = (int)event.getY();
            Log.d("DRAG", x + "," + y);
        }
        if(action == DragEvent.ACTION_DRAG_ENDED){
            Log.d("DRAG", "Dropped at " + x + "," + y);
            view.layout(x-(view.getWidth()/2), y-(view.getHeight()/2), x+(view.getWidth()/2), y+(view.getHeight()/2));
            view.setVisibility(View.VISIBLE);
        }
        return true;
    }
}

ZoomOutPageTransformer.java

package com.example.layouttest;

import android.support.v4.view.ViewPager.PageTransformer;
import android.view.View;

public class ZoomOutPageTransformer implements PageTransformer {
    private static float MIN_SCALE = 0.85f;
    private static float MIN_ALPHA = 0.5f;

    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();
        int pageHeight = view.getHeight();

        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.setAlpha(0);

        } else if (position <= 1) { // [-1,1]
            // Modify the default slide transition to shrink the page as well
            float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
            float vertMargin = pageHeight * (1 - scaleFactor) / 2;
            float horzMargin = pageWidth * (1 - scaleFactor) / 2;
            if (position < 0) {
                view.setTranslationX(horzMargin - vertMargin / 2);
            } else {
                view.setTranslationX(-horzMargin + vertMargin / 2);
            }

            // Scale the page down (between MIN_SCALE and 1)
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);

            // Fade the page relative to its size.
            view.setAlpha(MIN_ALPHA +
                    (scaleFactor - MIN_SCALE) /
                    (1 - MIN_SCALE) * (1 - MIN_ALPHA));

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0);
        }
    }
}

myfragment_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/layout"
    android:background="#00308F" >

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:onClick="click"
        android:text="@string/hello_world" />

</RelativeLayout>

shape.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle">

    <stroke 
        android:width="2dp"
        android:color="#FFFFFF" />
    <gradient 
        android:angle="225"
        android:endColor="#FFFFFF"
        android:startColor="#000000" />
    <corners 
        android:bottomLeftRadius="7dp"
        android:bottomRightRadius="7dp"
        android:topLeftRadius="7dp"
        android:topRightRadius="7dp" />

</shape>

activity_page_view.xml

<RelativeLayout 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.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</RelativeLayout>

如果有人能找到我的代码中的缺陷或让我知道如何在添加新图像时保持图像就位,我将不胜感激。

如果有人想亲眼目睹该问题,这里有一个 .apk 链接:LayoutTest.apk

最佳答案

问题已解决。

我去过的地方

view.layout(x-(view.getWidth()/2), y-(view.getHeight()/2), x+(view.getWidth()/2), y+(view.getHeight()/2));

我需要有

view.setX(x-(view.getWidth()/2));
view.setY(y-(view.getHeight()/2));

显然,.layout()是依赖于 View 层次结构的相对定位,而.setX().setY() > 是独立于层次结构的绝对定位。当新 View 添加到布局中时,层次结构会发生变化,受影响的任何内容都会返回到其默认起始位置。对于 xml 添加的 View ,定义了默认位置,但对于以编程方式添加的 View ,默认位置为 (0,0)。

要解决这个问题,我所要做的就是用两条新线替换该线,一切正常!

关于android - 拖放持久位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16990247/

相关文章:

android - 改造 response.errorBody() 为空

java - Android - 搜索框未出现

android - 如何在 fragment 中创建 editText

android - 在 View 分页器中的页面之间移动时,Edittext 自动获得焦点

javascript - 在页面上拖放文件——缺乏一致的解决方案

android - android中 native 网络相关功能随机阻塞

android - 如何在android中为一个按钮设置不同的文字大小?

java - Android - 在Fragment中显示WebView

Javascript 不识别点击事件

javascript - 使用Javascript获取拖放文件图标