Sunday, January 13, 2019

Kéo view đến một vị trí xác định

Ta đã có thể kéo view tự do trên màn hình. Bây giờ ta muốn kéo view đến vị trí nhất định, view sẽ dừng đúng vị trí đó, chưa đúng vị trí nó sẽ bật lại vị trí ban đầu.
Tạo một file keo.xml trong layout như sau.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="10dp"
android:paddingLeft="50dp"
android:paddingRight="50dp" >
<TextView
android:id="@+id/option_1"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_margin="5dp"
android:background="#00ffff"
android:gravity="center"
android:text="Apple"
android:textStyle="bold" />
<TextView
android:id="@+id/option_2"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_margin="5dp"
android:background="#0000ff"
android:gravity="center"
android:text="Orange"
android:textStyle="bold" />
<TextView
android:id="@+id/option_3"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_margin="5dp"
android:background="#008000"
android:gravity="center"
android:text="Ball"
android:textStyle="bold" />
<TextView
android:id="@+id/choice_1"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_margin="5dp"
android:background="#00ffff"
android:gravity="center"
android:text="A for " />
<TextView
android:id="@+id/choice_2"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_margin="5dp"
android:background="#00ffff"
android:gravity="center"
android:text="O for " />
<TextView
android:id="@+id/choice_3"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_margin="5dp"
android:background="#00ffff"
android:gravity="center"
android:text="B for " />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Reset"
android:onClick="reset"/>
</LinearLayout>
Class điều khiển như sau.
public class keoview extends Activity {
private TextView option1, option2, option3, choice1, choice2, choice3;
public CharSequence dragData;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.keo);
    //get both sets of text views
    //views to drag
    option1 = (TextView)findViewById(R.id.option_1);
    option2 = (TextView)findViewById(R.id.option_2);
    option3 = (TextView)findViewById(R.id.option_3);
    //views to drop onto
    choice1 = (TextView)findViewById(R.id.choice_1);
    choice2 = (TextView)findViewById(R.id.choice_2);
    choice3 = (TextView)findViewById(R.id.choice_3);
    //set touch listeners
    option1.setOnTouchListener(new ChoiceTouchListener());
    option2.setOnTouchListener(new ChoiceTouchListener());
    option3.setOnTouchListener(new ChoiceTouchListener());
    //set drag listeners
    choice1.setOnDragListener(new ChoiceDragListener());
    choice2.setOnDragListener(new ChoiceDragListener());
    choice3.setOnDragListener(new ChoiceDragListener());
}
private final class ChoiceTouchListener implements OnTouchListener {
    @SuppressLint("NewApi")
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            ClipData data = ClipData.newPlainText("", "");
            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
            //start dragging the item touched
            view.startDrag(data, shadowBuilder, view, 0);
            return true;
        } else {
            return false;
        }
    }
}
@SuppressLint("NewApi")
private class ChoiceDragListener implements OnDragListener {

    @Override
    public boolean onDrag(View v, DragEvent event) {
        switch (event.getAction()) {
        case DragEvent.ACTION_DRAG_STARTED:
            //no action necessary
            break;
        case DragEvent.ACTION_DRAG_ENTERED:
            //no action necessary
            break;
        case DragEvent.ACTION_DRAG_EXITED:       
            //no action necessary
            break;
        case DragEvent.ACTION_DROP:

            View view = (View) event.getLocalState();
            //view dragged item is being dropped on
            TextView dropTarget = (TextView) v;
            //view being dragged and dropped
            TextView dropped = (TextView) view;
            //checking whether first character of dropTarget equals first character of dropped
            if(dropTarget.getText().toString().charAt(0) == dropped.getText().toString().charAt(0))
            {
                //stop displaying the view where it was before it was dragged
                view.setVisibility(View.INVISIBLE);
                //update the text in the target view to reflect the data being dropped
                dropTarget.setText(dropTarget.getText().toString() + dropped.getText().toString());
                //make it bold to highlight the fact that an item has been dropped
                dropTarget.setTypeface(Typeface.DEFAULT_BOLD);
                //if an item has already been dropped here, there will be a tag
                Object tag = dropTarget.getTag();
                //if there is already an item here, set it back visible in its original place
                if(tag!=null)
                {
             //the tag is the view id already dropped here
                    int existingID = (Integer)tag;
                    //set the original view visible again
                    findViewById(existingID).setVisibility(View.VISIBLE);
                }
                //set the tag in the target view being dropped on - to the ID of the view being dropped
                dropTarget.setTag(dropped.getId());
                //remove setOnDragListener by setting OnDragListener to null, so that no further drag & dropping on this TextView can be done
                dropTarget.setOnDragListener(null);
            }
            else
                //displays message if first character of dropTarget is not equal to first character of dropped
                Toast.makeText(keo3.this, dropTarget.getText().toString() + "is not " + dropped.getText().toString(), Toast.LENGTH_LONG).show();
            break;
        case DragEvent.ACTION_DRAG_ENDED:
            break;
        default:
            break;
        }
        return true;
    }
}
public void reset(View view)
{
    option1.setVisibility(TextView.VISIBLE);
    option2.setVisibility(TextView.VISIBLE);
    option3.setVisibility(TextView.VISIBLE);

    choice1.setText("A for ");
    choice2.setText("O for ");
    choice3.setText("B for ");

    choice1.setTag(null);
    choice2.setTag(null);
    choice3.setTag(null);

    choice1.setTypeface(Typeface.DEFAULT);
    choice2.setTypeface(Typeface.DEFAULT);
    choice3.setTypeface(Typeface.DEFAULT);

    choice1.setOnDragListener(new ChoiceDragListener());
    choice2.setOnDragListener(new ChoiceDragListener());
    choice3.setOnDragListener(new ChoiceDragListener());
}
}
Tôi giữ lại một số dòng giải thích gốc để bạn tự đọc.

Cách này có thể vận dụng mở rộng để làm game.


No comments:

Post a Comment