I am working on something that needed custom drag-and-drop functionality, so I have been subclassing View, doing a bunch of math in response to touch events, and then rendering everything manually through code on the canvas in onDraw. Now, the more functionality I add, the more the code is growing out of control and I find myself writing a ton more code than I would expect to write in a high level environment like Android.
Is this how it's done, or am I missing something? If I'm not doing anything fancy in the UI, the framework handles the majority of my interactions. Built-in controls handle the touches and drags, and my code is pretty much limited to business logic and data. Is there a way to leverage the power of some of the UI controls and things like animations while also doing some of it manually in the onDraw canvas? Is there an accepted standard of when to use one or the other (if indeed the two approaches can be mixed)?
I use drag and drop in my music player application! I give to user the ability to move an song from an playlist to an other playlist. It is really nice and simple for the user. I start the drag event for my view when user make an long tap on an song or when an option from an menu is selected! This is my class:
package com.liviu.app.smpp.gui;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.liviu.app.smpp.R;
import com.liviu.app.smpp.listeners.CollisionListener;
public class SongItemView extends RelativeLayout implements OnClickListener {
// data
private String TAG = "SongItemView";
private Context context;
private LayoutInflater lInflater;
private String title;
private int id;
private int maxHeight = 410;
private int mCurX;
private int mCurY;
//listeners
private CollisionListener onCollisionListener = null;
// views
private View v;
public SongItemView(Context ctx, String title_, int id_) {
super(ctx);
context = ctx;
lInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = lInflater.inflate(R.layout.song_item_view, null);
title = title_;
id = id_;
((TextView)v.findViewById(R.id.siv_title)).setText(title);
addView(v, new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
@Override
public void onClick(View v) {
Log.e(TAG, "clicked! " + ((TextView)v.findViewById(R.id.piv_title)).getText().toString());
}
public View getView(){
return v;
}
public String getPlsName() {
return title;
}
public int getID() {
return id;
}
public void setTitle(String title_){
((TextView)v.findViewById(R.id.siv_title)).setText(title_);
title = title_;
}
public void setID(int id_) {
id = id_;
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
mCurX = (int) event.getRawX();
mCurY = (int) event.getRawY();
int action = event.getAction();
if (action == MotionEvent.ACTION_MOVE)
{
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.leftMargin = mCurX;
params.topMargin = mCurY;
this.setLayoutParams(params);
if(this.getTop() >= maxHeight)
{
Log.e(TAG, "Collision!!!!");
if(onCollisionListener != null){
onCollisionListener.onCollision(this);
}
}
}
return true;
}
public void setOnCollisionListener(CollisionListener listener){
onCollisionListener = listener;
}
public void setMaxHeight(int height){
maxHeight = height;
}
public int getmCurX() {
return mCurX;
}
public int getmCurY() {
return mCurY;
}
public int getMaxHeight() {
return maxHeight;
}
}
I hope this will help a bit.
Thanks!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With