I am woking on a project that uses drag and drop views within a relative layout. I have a button that generates a new image view when clicked. This image view is created in the top left corner of the screen, (0,0) relative to the parent view. I can then drag and drop the image view anywhere I want. Here's the problem: When I click the button again to make another image view, all of the image views move to the top left corner. Is Is there a different add method I should use or some way to keep the other image views in place? All the code is posted below.
Code:
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>
I would be greatly appreciative if anyone can find the flaw in my code or let me know how to keep my images in place when adding a new one.
Here is a link for the .apk if anyone would like to see the problem firsthand: LayoutTest.apk