Drag and Drop icons to Home Screen - java

Update:
to understand my question, here is what i need to achieve:
Drag icon from App drawer to home screen (if possible not in a gridview) like in the pic,
Old (this just to learn how this works):
I'm trying to implement dragging clickable icons from a ListView to a customView with no container(Listview or Gridview...) inside the same Activity or another, here is a picture for you to understand more:
but when i put the icon in the right area i don't see the object, in the log i see: I/ViewRootImpl﹕ Reporting drop result: true
here my code:
class MyDragListener implements View.OnDragListener {
#Override
public boolean onDrag(View v, DragEvent event) {
int action = event.getAction();
switch (event.getAction()) {
...
case DragEvent.ACTION_DROP:
LinearLayoutAbsListView itemo = (LinearLayoutAbsListView)findViewById(R.id.paneko);
View child = getLayoutInflater().inflate(R.layout.list_item, null);
itemo.addView(child);
break;
case DragEvent.ACTION_DRAG_ENDED:
default:
break;
}
return true;
}
}
My XML file:
...
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:background="#android:color/background_dark"
android:orientation="horizontal" >
<com.moapps.elfassimounir.simple.LinearLayoutAbsListView
android:id="#+id/paneuj"
android:background="#android:color/background_light"
android:orientation="vertical"
>
<ListView
android:id="#+id/listview1"
android:layout_width="100dp"
android:layout_height="wrap_content" />
</com.moapps.elfassimounir.simple.LinearLayoutAbsListView>
<com.moapps.elfassimounir.simple.LinearLayoutAbsListView
android:id="#+id/paneko"
android:background="#android:color/background_light"
android:orientation="vertical" >
</com.moapps.elfassimounir.simple.LinearLayoutAbsListView>
</LinearLayout>
...
Any infos or references (tutorials, docs...) would be very helpful

Have a look at adding a view to the WindowManager(WM). When you long press on an item to be dragged, create your own bitmap of that item and add it to the WM, so that it can be moved without view boundary constraints. When you receive a ACTION_UP or an equivalent event, map your current x,y to the actual view that is directly below the dragged item (Rect classs might be helpful). You can then add this item to that particular view.

Related

Grouping EditText

I was wondering if there is a way to group EditText in a way that you can only traverse among a group of them.
The problem is that I rely on reaching the end of the first group and use EditorInfo.IME_ACTION_DONE in order to trigger a certain action.
The inner group of EditTexts is inside a LinearLayout.
Put the text boxes in a layout(linear or relative) only those EditText which you want to make a group. layout will act as group. Add this on your every Edittext xml--
android:maxLines="1"
if it does not works the you can handle focus.
Focus Handling
Focus movement is based on an algorithm which finds the nearest neighbor in a given direction. In rare cases, the default algorithm may not match the intended behavior of the developer.
Change default behaviour of directional navigation by using following XML attributes:
android:nextFocusDown="#+id/.."
android:nextFocusLeft="#+id/.."
android:nextFocusRight="#+id/.."
android:nextFocusUp="#+id/.."
Besides directional navigation you can use tab navigation. For this you need to use
android:nextFocusForward="#+id/.."
To get a particular view to take focus, call
view.requestFocus()
To listen to certain changing focus events use a View.OnFocusChangeListener
Keyboard button
You can use android:imeOptions for handling that extra button on your keyboard.
Additional features you can enable in an IME associated with an editor to improve the integration with your application. The constants here correspond to those defined by imeOptions.
The constants of imeOptions includes a variety of actions and flags, see the link above for their values.
Value example
ActionNext :
the action key performs a "next" operation, taking the user to the next field that will accept text.
ActionDone :
the action key performs a "done" operation, typically meaning there is nothing more to input and the IME will be closed.
Code example:
<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"
tools:context=".MainActivity" >
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="32dp"
android:layout_marginTop="16dp"
android:imeOptions="actionNext"
android:singleLine="true"
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editText1"
android:layout_below="#+id/editText1"
android:layout_marginTop="24dp"
android:imeOptions="actionDone"
android:singleLine="true"
android:ems="10" />
</RelativeLayout>
If you want to listen to imeoptions events use a TextView.OnEditorActionListener.
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
performSearch();
return true;
}
return false;
}
});
Edit:
For dynamic edittext you can try..
EditText etCurrent;
Set an OnTouchlistener on each EditText:
valueET.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (etCurrent != null) {
if (etCurrent.getId() != v.getId()) {
if (!check(etCurrent.getId())) {
etCurrent.setSelection(0,
etCurrent.getText().toString().length());
return true;
} else {
etCurrent = (EditText) v;
}
}
} else {
etCurrent = (EditText) v;
}
}
return false;
}
});

TextView with scrollbar that can handle onTouchEvents

I have problem with handling Touch events inside my TextView on Android 2.3.3. I've got Activity implements OnTouchListener with method
main.java
public boolean onTouchEvent(MotionEvent event) {
if(event.getPointerCount()==1){
textView.setTextSize(mRatio+13);
mRatio++;
Log.d("TouchEvent", "one touch !");
}
if (event.getPointerCount() == 2) {
some code...
}
return true;
}
and my layout(only part of it):
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1.0"
android:fadingEdge="none"
android:background="#color/white">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="10dp">
<!-- TEXT EMAIL : -->
<TextView
android:id="#+id/mail_text"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:textSize="15sp"
android:autoLink="web"
android:clickable="true"
android:textColor="#color/mailtext"
android:scrollbars = "vertical"/>
</LinearLayout>
</LinearLayout>
When i 'clicked' anywhere outside my textBox(for example on header or footer), the Touch event trigger, font get bigger. I assume than the problem is probably because scrollbars. But when I cut off android:scrollbars = "vertical" bar just disappear.
This textView usually contain a lots of text.
How to proper fire onTouchEvents inside this textView.
Edit:
when this textView is small my touchEvent work until i get text so big, than the scrollBar is needed. Then all touch event get overrided and You can only scroll textView. No TouchEvent is called.
I handle the problem in other way. OnTouchEvent didn't worked with my TextView so I Override dispatchTouchEvent. It's far more better to performe actions "onTouch".Scrollbar is working and I can add my multitouch events on the whole screen. It's look like:
#Override
public boolean dispatchTouchEvent(MotionEvent motionEvent){
Log.v("NotificationActivity.dispatchTouchEvent()", "got touch");
if (motionEvent.getPointerCount() == 2) {
Log.v("touch", "multi touch !");
int action = motionEvent.getAction();
int pureaction = action & MotionEvent.ACTION_MASK;
// some actions ...
}
switch (motionEvent.getAction()){
case MotionEvent.ACTION_DOWN:{
//Keep track of the starting down-event.
Log.v("akcjaa","down");
// some actions ...
break;
}
case MotionEvent.ACTION_UP:{
//Consume if necessary and perform the fling / swipe action
//if it has been determined to be a fling / swipe
Log.v("akcjaa","up");
break;
}
}
return super.dispatchTouchEvent(motionEvent);
}
I am assuming your TextView is inside some kind of ScrollView or Scrollable container, right?
Then you will face this issue. Android does not like his apples and pears mixed, you should not be trying to receive "onTouch" events that are being consumed by the father layout on top of the view.
I guess you could:
a) Switch to a onClickListener on your TextView
b) Override your parent view layout touch handler to bleed the touch down to its childs. This is not really 100% recommended, and could cause unwanted behaviour.
Sorry if i cannot be of more help.

How to get `ListView` item to wrap_content starting from right side of the screen?

I have a ListView that has a custom adapter to provide a customized View. Each list item "changes" the side of the screen it is on (as if you flipped it around a vertical axis). Here's an example of what I'm talking about:
The darker gray boxes in the photo cover up a ProfilePictureView and a TextView containing a users name and photo. No name and photo if the user is not logged in (as you can see in the second list item in the photo). As you can see from the photo, the background image wraps around the content in the view for the first and third item (starting from the left and ending at the right).The problem is: the items facing the other way are ignoring my "wrap_content" call and are "matching" the parent view (as you can see in item two). I believe it is correctly wrapping the content but is there any way to start from the right of the screen and wrap content to the left?
Here's the XML code for that items view:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right|center_vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentRight="true"
android:gravity="right" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.namespace.RobotoTextView
android:id="#+id/list_item_user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="#color/white"
custom:typeface="roboto_light"/>
<com.namespace.RobotoTextView
android:id="#+id/list_item_user_score"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="36sp"
android:textStyle="bold"
android:textColor="#color/waf_warm_yellow_orange"
custom:typeface="roboto_bold"/>
</LinearLayout>
<com.facebook.widget.ProfilePictureView
android:id="#+id/list_item_user_image"
android:layout_width="69dp"
android:layout_height="69dp"
android:layout_margin="10dp" />
</LinearLayout>
So, how can I align the view correctly to the right and have the background image correctly wrap around its content?
Create a separate list item layout for left and right. In your adapter...
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int position) {
return position % 2;
}
public View getView(int position, View convertView, ViewGroup parent) {
int viewType = getItemViewType(position);
int layoutRes = viewType == 0 ? R.layout.list_item_left : R.layout.list_item_right;
View row = inflater.inflate(layoutRes);
/* ... */
}
Basically, your adapter reports two different view types and your getView alternates between them. (If there's some other logic to determine left vs. right, implement it in getItemViewType().)
The answer to my problem was quite simple, inside my custom adapter I was setting the background image resource depending on whether it was an even or odd listview item. Instead of doing that I just had to make an imageview and set that image resource to the background image and set it to the correct side of the screen with the android:layout_alignParentRight="true and `android:layout_alignParentLeft="true" attributes.

Drag and Drop functionality for multiple images

I was wondering if there's any tutorial having a drag and drop functionality on differing images making them target specific?
By this I mean, If you have say, 4 draggable images; image_drag_1, image_drag_2, image_drag_3, and image_drag_4 and 4 drop_target images; image_drop_1, image_drop_2, image_drop_3 and image_drop_4.
image_drag_1 should be matched to image_drop_1 and any attempt to drop image_drag_1 on any other drop image or location in the screen layout, makes image_drag_1 snap back to its original position.
This tutorial implements a drag drop functionality for textview, though not target specify.
I have tried on my own implementing my own drag and drop following the tutorual stated above, leaving textview to be draggable and the imageviews, the drop targets. It just crashes my emulator.
Below can be found my .java file:
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View.DragShadowBuilder;
import android.view.View.OnDragListener;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.content.ClipData;
import android.graphics.Typeface;
public class MainActivity extends Activity {
//Imageview to drag the image is dragged into
private ImageView image1, image2;
//textview the image is dragged into
private TextView choice1, choice2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//views to drag
image1 = (ImageView)findViewById(R.id.imageView1);
image2 = (ImageView)findViewById(R.id.imageButton1);
//views to drop onto
choice1 = (TextView)findViewById(R.id.choice_1);
choice2 = (TextView)findViewById(R.id.choice_2);
//set touch listeners
image1.setOnTouchListener(new ChoiceTouchListener());
image2.setOnTouchListener(new ChoiceTouchListener());
//set drag listeners
choice1.setOnDragListener(new ChoiceDragListener());
choice2.setOnDragListener(new ChoiceDragListener());
}
private final class ChoiceTouchListener implements OnTouchListener {
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
/*
* Drag details: we only need default behavior
* - clip data could be set to pass data as part of drag
* - shadow can be tailored
*/
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;
}
}
}
/**
* DragListener will handle dragged views being dropped on the drop area
* - only the drop action will have processing added to it as we are not
* - amending the default behavior for other parts of the drag process
*
*/
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:
//handle the dragged view being dropped over a drop view
View view = (View) event.getLocalState();
//stop displaying the view where it was before it was dragged
view.setVisibility(View.INVISIBLE);
//view dragged item is being dropped on
TextView dropTarget = (TextView) v;
//view being dragged and dropped
ImageView dropped = (ImageView) view;
//update the text in the target view to reflect the data being dropped
dropTarget.setText(dropped.getImageAlpha());
//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());
break;
case DragEvent.ACTION_DRAG_ENDED:
//no action necessary
break;
default:
break;
}
return true;
}
}
}
My xml file is as below:
<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"
tools:context=".MainActivity" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="66dp"
android:orientation="vertical"
android:padding="10dp"
android:paddingLeft="50dp"
android:paddingRight="50dp" >
<TextView
android:id="#+id/choice_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_marginTop="46dp"
android:background="#drawable/choice"
android:gravity="center"
android:text="#string/choice_1" />
<TextView
android:id="#+id/choice_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_marginTop="57dp"
android:background="#drawable/choice"
android:gravity="center"
android:text="#string/choice_2" />
</LinearLayout>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/linearLayout1"
android:layout_marginBottom="16dp"
android:layout_toRightOf="#+id/imageButton1"
android:contentDescription="#string/image_desc"
android:src="#drawable/firefighter" />
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:contentDescription="#string/image_desc"
android:src="#drawable/clown" />
Any advise as to what I'm doing wrong? Thanks in advance.

Finding the ID of a widget in a view class

What I have is a canvas that takes up nearly all of the screen, then under that I want a row of buttons and some other widgets. So I did this.
XML Code
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="#+id/myLayout"
android:orientation="vertical"
android:layout_height="match_parent" >
<com.zone.manager.Tab3
android:id="#+id/tab3_display"
android:layout_width="fill_parent"
android:layout_height="620dp" />
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="match_parent" >
<Button
android:id="#+id/addZone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Zone" />
<Button
android:id="#+id/helpZone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Help" />
<SeekBar
android:id="#+id/seekBar1"
android:paddingTop="9dp"
android:layout_width="179dp"
android:layout_height="wrap_content" />
</LinearLayout>
Java Code
public class Tab3 extends View implements OnTouchListener, OnClickListener {
public Tab3(Context context, AttributeSet attrs) {
View parent = (View) getParent();
addZone = (Button) parent.findViewById(R.id.addZone);
addZone.setOnClickListener(this);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
. . . draws a bunch of stuff
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.addZone:
String w = "W~20~0~0~0~0~0";
Log.d("ZoneSize", "Zone set");
MyApplication.preferences.edit().putString( "ZoneSize", w ).commit();
MyApplication.preferences.edit().putBoolean("ZoneSizeReady", true).commit();
break;
}
}
However my problem with this is that I believe the code is not reconising where the addZone is. Because when I have the addZone.setOnClickListener active my program will crash, but when I don't have it active the layout looks like how I want it. What must I do to fix this?
addZone = (Button) findViewById(R.id.addZone);
addZone will be null because com.zone.manager.Tab3 does not have any children
So it is obvious that your code will crash
So either you will give com.zone.manager.Tab children which require also to change the base class from View to ViewGroup,
or you start with com.zone.manager.Tab parent. Something like
View parent = (View) getParent ();
addZone = (Button) parent.findViewById(R.id.addZone);
i have some tips which will make you avoid such weird bugs and others:
the code of the custom view relies on an xml layout that uses the custom view .
this is bad coding.
instead, you should use LayoutInflater , use a layout xml file for the custom view for it , and then do the "findViewById" and add the clickListeners to any view inside that you wish.
i think it's also wrong to set the custom view to hold the click listener of the other views without checking which of them was clicked . either add a check , or add a different listener for each of them (which i personally prefer) .

Categories