does anyone have an idea to do this i would be happy if i am suggested.
creating a custom view
Page 1 of 19 Replies - 682 Views - Last Post: 11 December 2012 - 10:43 AM
#1
creating a custom view
Posted 03 December 2012 - 09:56 AM
Does any one have any idea of creating a custom component like the below image instead of using the image itself. I know how to create a rectangle (a rounded one using the xml and not in java) which was discussed in most of the links but i am not able to work with something like the pointer part.
does anyone have an idea to do this i would be happy if i am suggested.
does anyone have an idea to do this i would be happy if i am suggested.
Replies To: creating a custom view
#2
Re: creating a custom view
Posted 07 December 2012 - 01:32 PM
Take a look at the Canvas drawLine() method. If you can draw the rest of the shape, drawing the two lines shouldn't be too bad. To get the border around the rounded rectangle, you may need to drawArc().
#3
Re: creating a custom view
Posted 07 December 2012 - 11:03 PM

POPULAR
I would use the PopupWindow and make the "bubble" as a 9-patch image and then the "pointer" as a separate image.
Then as a ListView or TextView inside it. If the Window's Height and Width is set to "warp_content", then it will resize it self according to the length of the content.
I have 2 classes (at a total of 537 lines of code) then will work for you.
First of, you'll need a custom PopupWindow:
Then, you'll need a class i call QuickAction:
To using it, will need to create the content of it (in my case, it's item of a ListView)
Then, you need to create the QuickAction-object and add the items:
Then you'll need a listener (separate):
Then you'll need to set the listener:
There will be some error in the code, because you don't have the images in your project.
If you wan't the Popup to dismiss when the user press back-key or taps outside it, then will need to add this after you added the items:
You will also need 4 xml-layouts:
popup_vertical.xml:
popup_horizontal.xml :
action_item_vertical.xml :
and action_item_horizontal.xml:
and again, there will be some errors, because you don't have the images and/or colors the is specified in the code.
But i hope this helps.
You may use this code in any way you want.
Cheers
Then as a ListView or TextView inside it. If the Window's Height and Width is set to "warp_content", then it will resize it self according to the length of the content.
I have 2 classes (at a total of 537 lines of code) then will work for you.
First of, you'll need a custom PopupWindow:
package com.groove.mobile.specials;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.widget.PopupWindow;
import android.content.Context;
/**
* This is for the custom Popup windows used in GrooveMobile.
* The app allow anyone to listen to music from Grooveshark on there Android-device for free.
* All code is copywrited to the authors! The main-library is writen by scilor!
* Non of the authors are related to Grooveshark in any way!
* @author Pontus Holmberg (EndLessMind)
* Email: the_mr_hb@hotmail.com
**/
public class PopupWindows {
protected Context mContext;
public PopupWindow mWindow;
protected View mRootView;
protected Drawable mBackground = null;
protected WindowManager mWindowManager;
/**
* Constructor.
*
* @param context Context
*/
public PopupWindows(Context context) {
mContext = context;
mWindow = new PopupWindow(context);
mwindow.setBackgroundDrawable(new BitmapDrawable());
mwindow.setTouchInterceptor(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
mwindow.dismiss();
return true;
}
return false;
}
});
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
}
/**
* On dismiss
*/
protected void onDismiss() {
}
/**
* On show
*/
protected void onShow() {
}
/**
* On pre show
*/
protected void preShow() {
if (mRootView == null)
throw new IllegalStateException("setContentView was not called with a view to display.");
onShow();
// if (mBackground == null)
// mwindow.setBackgroundDrawable(new BitmapDrawable());
//else
// mwindow.setBackgroundDrawable(new BitmapDrawable());
mwindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
mwindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
// mwindow.setTouchable(true);
// mwindow.setFocusable(true);
// mwindow.setOutsideTouchable(true);
mwindow.setContentView(mRootView);
}
/**
* Set background drawable.
*
* @param background Background drawable
*/
public void setBackgroundDrawable(Drawable background) {
mwindow.setBackgroundDrawable(background);
}
/**
* Set content view.
*
* @param root Root view
*/
public void setContentView(View root) {
mRootView = root;
mwindow.setContentView(root);
}
/**
* Set content view.
*
* @param layoutResID Resource id
*/
public void setContentView(int layoutResID) {
LayoutInflater inflator = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
setContentView(inflator.inflate(layoutResID, null));
}
/**
* Set listener on window dismissed.
*
* @param listener
*/
public void setOnDismissListener(Popupwindow.OnDismissListener listener) {
mwindow.setOnDismissListener(listener);
}
/**
* Dismiss the popup window.
*/
public void dismiss() {
mwindow.dismiss();
}
}
Then, you'll need a class i call QuickAction:
package com.groove.mobile.specials;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ScrollView;
import android.widget.RelativeLayout;
import android.widget.Popupwindow.OnDismissListener;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.onclickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup;
import java.util.List;
import java.util.ArrayList;
import com.groove.mobile.R;
import com.groove.mobile.classes.ActionItem;
/**
* This is for the custom QuickAction dialogs used in GrooveMobile.
* The app allow anyone to listen to music from Grooveshark on there Android-device for free.
* All code is copywrited to the authors! The main-library is writen by scilor!
* Non of the authors are related to Grooveshark in any way!
* @author Pontus Holmberg (EndLessMind)
* Email: the_mr_hb@hotmail.com
**/
public class QuickAction extends PopupWindows implements OnDismissListener {
private View mRootView;
private ImageView mArrowUp;
private ImageView mArrowDown;
private LayoutInflater mInflater;
private ViewGroup mTrack;
private ScrollView mScroller;
private OnActionItemClickListener mItemClickListener;
private OnDismissListener mDismissListener;
private List<ActionItem> actionItems = new ArrayList<ActionItem>();
private boolean mDidAction;
public boolean isDismissed = false;
private int mChildPos;
private int mInsertPos;
private int mAnimStyle;
private int mOrientation;
private int rootWidth=0;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
public static final int ANIM_GROW_FROM_LEFT = 1;
public static final int ANIM_GROW_FROM_RIGHT = 2;
public static final int ANIM_GROW_FROM_CENTER = 3;
public static final int ANIM_REFLECT = 4;
public static final int ANIM_AUTO = 5;
public static View baseView = null;
/**
* Constructor for default vertical layout
*
* @param context Context
*/
public QuickAction(Context context) {
this(context, VERTICAL);
}
/**
* Constructor allowing orientation override
*
* @param context Context
* @param orientation Layout orientation, can be vartical or horizontal
*/
public QuickAction(Context context, int orientation) {
super(context);
mOrientation = orientation;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (mOrientation == HORIZONTAL) {
setRootViewId(R.layout.popup_horizontal);
} else {
setRootViewId(R.layout.popup_vertical);
}
mAnimStyle = ANIM_AUTO;
mChildPos = 0;
}
/**
* Get action item at an index
*
* @param index Index of item (position from callback)
*
* @return Action Item at the position
*/
public ActionItem getActionItem(int index) {
return actionItems.get(index);
}
public View GetBaseView() {
return baseView;
}
/**
* Set root view.
*
* @param id Layout resource id
*/
public void setRootViewId(int id) {
// setOutsideTouchable(true);
mRootView = (ViewGroup) mInflater.inflate(id, null);
mTrack = (ViewGroup) mRootView.findViewById(R.id.tracks);
mArrowDown = (ImageView) mRootView.findViewById(R.id.arrow_down);
mArrowUp = (ImageView) mRootView.findViewById(R.id.arrow_up);
mScroller = (ScrollView) mRootView.findViewById(R.id.scroller);
//This was previously defined on show() method, moved here to prevent force close that occured
//when tapping fastly on a view to show quickaction dialog.
//thanks to zammbi (github.com/zammbi)
mRootView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
setContentView(mRootView);
}
/**
* Set animation style
*
* @param mAnimStyle animation style, default is set to ANIM_AUTO
*/
public void setAnimStyle(int mAnimStyle) {
this.mAnimStyle = mAnimStyle;
}
/**
* Set listener for action item clicked.
*
* @param listener Listener
*/
public void setOnActionItemClickListener(OnActionItemClickListener listener) {
mItemClickListener = listener;
}
/**
* Add action item
*
* @param action {@link ActionItem}
*/
public void addActionItem(ActionItem action) {
actionItems.add(action);
String title = action.getTitle();
Drawable icon = action.getIcon();
View container;
if (mOrientation == HORIZONTAL) {
container = mInflater.inflate(R.layout.action_item_horizontal, null);
} else {
container = mInflater.inflate(R.layout.action_item_vertical, null);
}
ImageView img = (ImageView) container.findViewById(R.id.iv_icon);
TextView text = (TextView) container.findViewById(R.id.tv_title);
if (icon != null) {
img.setImageDrawable(icon);
} else {
img.setVisibility(View.GONE);
}
if (title != null) {
text.setText(title);
} else {
text.setVisibility(View.GONE);
}
final int pos = mChildPos;
final int actionId = action.getActionId();
container.setonclickListener(new onclickListener() {
public void onclick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClick(QuickAction.this, pos, actionId);
}
if (!getActionItem(pos).isSticky()) {
mDidAction = true;
dismiss();
}
}
});
container.setFocusable(true);
container.setClickable(true);
if (mOrientation == HORIZONTAL && mChildPos != 0) {
View separator = mInflater.inflate(R.layout.horiz_separator, null);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
separator.setLayoutParams(params);
separator.setPadding(5, 0, 5, 0);
mTrack.addView(separator, mInsertPos);
mInsertPos++;
}
mTrack.addView(container, mInsertPos);
mChildPos++;
mInsertPos++;
}
/**
* Show quickaction popup. Popup is automatically positioned, on top or bottom of anchor view.
*
*/
public void show (View anchor) {
preShow();
this.baseView = anchor;
int xPos, yPos, arrowPos;
mDidAction = false;
int[] location = new int[2];
anchor.getLocationOnScreen(location);
Rect anchorRect = new Rect(location[0], location[1], location[0] + anchor.getWidth(), location[1]
+ anchor.getHeight());
//mRootView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mRootView.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
int rootHeight = mRootView.getMeasuredHeight();
if (rootWidth == 0) {
rootWidth = mRootView.getMeasuredWidth();
}
int screenWidth = mWindowManager.getDefaultDisplay().getWidth();
int screenHeight = mWindowManager.getDefaultDisplay().getHeight();
//automatically get X coord of popup (top left)
if ((anchorRect.left + rootWidth) > screenWidth) {
xPos = anchorRect.left - (rootWidth-anchor.getWidth());
xPos = (xPos < 0) ? 0 : xPos;
arrowPos = anchorRect.centerX()-xPos;
} else {
if (anchor.getWidth() > rootWidth) {
xPos = anchorRect.centerX() - (rootWidth/2);
} else {
xPos = anchorRect.left;
}
arrowPos = anchorRect.centerX()-xPos;
}
int dyTop = anchorRect.top;
int dyBottom = screenHeight - anchorRect.bottom;
boolean onTop = (dyTop > dyBottom) ? true : false;
if (onTop) {
if (rootHeight > dyTop) {
yPos = 15;
LayoutParams l = mScroller.getLayoutParams();
l.height = dyTop - anchor.getHeight();
} else {
yPos = anchorRect.top - rootHeight;
}
} else {
yPos = anchorRect.bottom;
if (rootHeight > dyBottom) {
LayoutParams l = mScroller.getLayoutParams();
l.height = dyBottom;
}
}
showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), arrowPos);
setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
mwindow.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos);
}
/**
* Set animation style
*
* @param screenWidth screen width
* @param requestedX distance from left edge
* @param onTop flag to indicate where the popup should be displayed. Set TRUE if displayed on top of anchor view
* and vice versa
*/
private void setAnimationStyle(int screenWidth, int requestedX, boolean onTop) {
int arrowPos = requestedX - mArrowUp.getMeasuredWidth()/2;
switch (mAnimStyle) {
case ANIM_GROW_FROM_LEFT:
mwindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);
break;
case ANIM_GROW_FROM_RIGHT:
mwindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);
break;
case ANIM_GROW_FROM_CENTER:
mwindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);
break;
case ANIM_REFLECT:
mwindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect : R.style.Animations_PopDownMenu_Reflect);
break;
case ANIM_AUTO:
if (arrowPos <= screenWidth/4) {
mwindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);
} else if (arrowPos > screenWidth/4 && arrowPos < 3 * (screenWidth/4)) {
mwindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);
} else {
mwindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);
}
break;
}
}
/**
* Show arrow
*
* @param whichArrow arrow type resource id
* @param requestedX distance from left screen
*/
private void showArrow(int whichArrow, int requestedX) {
final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp : mArrowDown;
final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown : mArrowUp;
final int arrowWidth = mArrowUp.getMeasuredWidth();
showArrow.setVisibility(View.VISIBLE);
ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams)showArrow.getLayoutParams();
param.leftMargin = requestedX - arrowWidth / 2;
hideArrow.setVisibility(View.INVISIBLE);
}
/**
* Set listener for window dismissed. This listener will only be fired if the quicakction dialog is dismissed
* by clicking outside the dialog or clicking on sticky item.
*/
public void setOnDismissListener(QuickAction.OnDismissListener listener) {
setOnDismissListener(this);
mDismissListener = listener;
}
@Override
public void onDismiss() {
if (!mDidAction && mDismissListener != null) {
isDismissed = true;
Log.d("Qick", "Dismissed-inside");
mDismissListener.onDismiss();
}
}
/**
* Listener for item click
*
*/
public interface OnActionItemClickListener {
public abstract void onItemClick(QuickAction source, int pos, int actionId);
}
/**
* Listener for window dismiss
*
*/
public interface OnDismissListener {
public abstract void onDismiss();
}
}
To using it, will need to create the content of it (in my case, it's item of a ListView)
ActionItem item_1= new ActionItem(1, "Item_1", getResources().getDrawable(R.drawable.item_1)); ActionItem item_2= new ActionItem(2, "Item_2", getResources().getDrawable(R.drawable.item_2));
Then, you need to create the QuickAction-object and add the items:
QuickAction quickAction = new QuickAction(this, QuickAction.VERTICAL);
quickAction.addActionItem(item_1);
quickAction.addActionItem(item_2);
Then you'll need a listener (separate):
private QuickAction.OnActionItemClickListener QuickAction_ItemClick = new QuickAction.OnActionItemClickListener() {
public void onItemClick(QuickAction source, int pos, int actionId) {
if (actionId == 1 ) {
//Do something when item_1 is clicked
} else if (actionId == 2) {
//Do something when item_2 is clicked
}
}
};
Then you'll need to set the listener:
quickAction.setOnActionItemClickListener(QuickAction_ItemClick);
There will be some error in the code, because you don't have the images in your project.
If you wan't the Popup to dismiss when the user press back-key or taps outside it, then will need to add this after you added the items:
quickAction.mwindow.setOutsideTouchable(true);
quickAction.mwindow.setBackgroundDrawable(new BitmapDrawable());
You will also need 4 xml-layouts:
popup_vertical.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ScrollView
android:id="@+id/scroller"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dip"
android:background="@color/Black"
android:fadingEdgeLength="5dip"
android:scrollbars="none" >
<LinearLayout
android:id="@+id/tracks"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dip"/>
</ScrollView >
<ImageView
android:id="@+id/arrow_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_up" />
<ImageView
android:id="@+id/arrow_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/scroller"
android:layout_marginTop="-4dip"
android:src="@drawable/arrow_down" />
</RelativeLayout>
popup_horizontal.xml :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ScrollView
android:id="@+id/scroller"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dip"
android:background="@color/Black"
android:fadingEdgeLength="5dip"
android:scrollbars="none" >
<LinearLayout
android:id="@+id/tracks"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:padding="10dip"/>
</ScrollView >
<ImageView
android:id="@+id/arrow_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_up" />
<ImageView
android:id="@+id/arrow_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/scroller"
android:layout_marginTop="-4dip"
android:src="@drawable/arrow_down" />
</RelativeLayout>
action_item_vertical.xml :
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:background="@drawable/action_item_btn">
<ImageView
android:id="@+id/iv_icon"
android:layout_width="30dp"
android:layout_height="30dp"/>
<TextView
android:id="@+id/tv_title"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:paddingLeft="5dip"
android:paddingRight="10dip"
android:layout_marginBottom="5dp"
android:layout_marginTop="3dp"
android:text="Chart"
android:textColor="#fff"/>
</LinearLayout>
and action_item_horizontal.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:background="@drawable/action_item_btn">
<ImageView
android:id="@+id/iv_icon"
android:layout_centerHorizontal="true"
android:layout_width="24dp"
android:layout_height="24dp"/>
<TextView
android:id="@+id/tv_title"
android:layout_below="@+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:paddingLeft="5dip"
android:paddingRight="5dip"
android:layout_marginBottom="5dp"
android:layout_marginTop="3dp"
android:text="Chart"
android:textColor="#fff"/>
</RelativeLayout>
and again, there will be some errors, because you don't have the images and/or colors the is specified in the code.
But i hope this helps.
You may use this code in any way you want.
Cheers
This post has been edited by EndLessMind: 07 December 2012 - 11:10 PM
#4
Re: creating a custom view
Posted 07 December 2012 - 11:04 PM
@EndLessMind: Neat! You might consider making that into a tutorial and submitting it to the DIC Holiday Contest.
#5
Re: creating a custom view
Posted 07 December 2012 - 11:12 PM
Thanks, missed somethings, but edited the post now and added them 
Merry Christmas to you all
Merry Christmas to you all
#6
Re: creating a custom view
Posted 07 December 2012 - 11:17 PM
Oh, and one more thing!
If you want to show it a onclickListener is called, then you can do like this:
Here is an image of that the finished product looks like when i use it

Cheers
If you want to show it a onclickListener is called, then you can do like this:
public void onclick(View v) {
quickAction.show(v);
}
Here is an image of that the finished product looks like when i use it

Cheers
#7
Re: creating a custom view
Posted 08 December 2012 - 04:57 PM
Sorry, forgot about the animations and styles. Posted a tutorial about it, hopefully it will be approved
#8
Re: creating a custom view
Posted 10 December 2012 - 10:10 AM
You can use with EndlessMind's tutorial, which is very nice, or you can just create a simple compoundview with a scrollview and generic view below it. Set the background of the scrollview to a rectshape, and the bottom part is a simple view with a custom Shape as a background. I am sure there are some compound view component tutorials in the tutorials section.
#9
Re: creating a custom view
Posted 11 December 2012 - 08:20 AM
Thanks a lot for the information.
Will check and be back if it gives me any problem.
Will check and be back if it gives me any problem.
#10
Re: creating a custom view
Posted 11 December 2012 - 10:43 AM
I'd se that i missed a bit in that post.
Please look at the tutorial called "PopupMenu, ContextMenu and Custom PopupWindow, all in one" linked in my signature
Please look at the tutorial called "PopupMenu, ContextMenu and Custom PopupWindow, all in one" linked in my signature
Page 1 of 1
|
|

New Topic/Question
Reply


MultiQuote









|