Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I would like to know how to make a layout, like in a Facebook App. I understand, not only me alone looking for it, but I cannot to find the correct words for the search system to find it. And may be here somebody will give me a good link with a sample code. I like a menu, which shows up from the left side in their App.
You can go for any of this link below you like, there are lots of docs and tutorial available.
Android sliding menu demo
Facebook-like slide out navigation for Android
How To Create A Slide-In MenuList, Like In Facebook App
Hope it will help you.
If you need a simple but effective one then you can see the code. I was using it in my last project.
You can download full source code here.
You can check my blog too if it helped you.
Main layout : res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<com.banglardin.test_code.SlidingView
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/list_activity_layout" >
<!-- Just make your sliding layout here -->
<LinearLayout
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FF34495E"
android:id="#+id/slide_bar_list_activity" >
<!-- All the layout of sliding goes here -->
</LinearLayout>
<!-- Just make your content layout here -->
<LinearLayout
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FF112131"
android:id="#+id/content_bar_list_activity" >
<!-- All the layout of content goes here -->
<RelativeLayout
android:id = "#+id/head1"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:layout_alignParentTop = "true"
android:background="#336699"
android:maxWidth="48dp" >
<ImageButton
android:id ="#+id/main_menu_action_left_of_lable"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentLeft = "true"
android:layout_centerVertical ="true"
android:layout_weight="1"
android:src="#drawable/option_menu"
android:background="#drawable/all_image_button_press"
android:padding="5dp"/>
<!-- Title lable Of home bar. -->
<TextView
android:id ="#+id/main_toptext"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
android:gravity="center"
android:layout_weight="2"
android:shadowDy=".4"
android:shadowDx=".4"
android:clickable="true"
android:shadowRadius=".7"
android:shadowColor="#000000"
android:textColor = "#ffffff"
android:layout_toRightOf="#+id/main_menu_action_left_of_lable"
android:layout_toLeftOf="#+id/main_right_of_lable"
android:layout_centerInParent ="true"
android:textSize = "18dp"
android:layout_centerVertical ="true"
android:padding="5dp"
android:text = " Shiba prasad jana "
android:singleLine = "true"/>
<!-- Search -->
<ImageButton
android:id ="#+id/main_right_of_lable"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentRight = "true"
android:layout_centerVertical ="true"
android:layout_weight="1"
android:src="#drawable/search_icon"
android:background="#drawable/all_image_button_press"
android:padding="5dp"/>
</RelativeLayout>
</LinearLayout>
MainActivity: src/package_name/MainActivity
package com.banglardin.test_code;
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;
public class MainActivity extends Activity implements SlidingView.Listener {
protected SlidingView mSlidingView;
protected ImageButton menu;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
mSlidingView=(SlidingView)findViewById(R.id.list_activity_layout);
mSlidingView.setListener(this);
menu = (ImageButton) findViewById(R.id.main_menu_action_left_of_lable);
menu.setOnClickListener(new View.OnClickListener(){
public void onClick(View p1){
mSlidingView.toggleSidebar();
}
}
);
}
public void onSidebarOpened() {
}
public void onSidebarClosed() {
}
public boolean onContentTouchedWhenOpening() {
return false;
}
}
SlidingView : src/package_name/SlidingView
package com.banglardin.test_code;
import android.util.*;
import android.view.*;
import android.view.animation.*;
import android.content.Context;
public class SlidingView extends ViewGroup {
public final static int DURATION = 400; // time to show slding animation
protected boolean mPlaceLeft = true;
protected boolean mOpened;
protected View mSidebar;
protected View mContent;
protected int mSidebarWidth =-1; /* assign default value. It will be overwrite
in onMeasure by Layout xml resource. */
protected Animation mAnimation;
protected OpenListener mOpenListener;
protected CloseListener mCloseListener;
protected Listener mListener;
protected boolean mPressed = false;
public SlidingView(Context context) {
this(context, null);
int mSidebarWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,50, getResources().getDisplayMetrics());
}
public SlidingView
(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void onFinishInflate() {
super.onFinishInflate();
mSidebar = findViewById(R.id.slide_bar_list_activity);
mContent = findViewById(R.id.content_bar_list_activity);
if (mSidebar == null) {
throw new NullPointerException("no view id = animation_sidebar");
}
if (mContent == null) {
throw new NullPointerException("no view id = animation_content");
}
mOpenListener = new OpenListener(mSidebar, mContent);
mCloseListener = new CloseListener(mSidebar, mContent);
}
#Override
public void onLayout(boolean changed, int l, int t, int r, int b) {
/* the title bar assign top padding, drop it */
int sidebarLeft = l;
if (!mPlaceLeft) {
sidebarLeft = r - mSidebarWidth;
}
mSidebar.layout(sidebarLeft,
0,
sidebarLeft + mSidebarWidth,
0 + mSidebar.getMeasuredHeight());
if (mOpened) {
if (mPlaceLeft) {
mContent.layout(l + mSidebarWidth, 0, r + mSidebarWidth, b);
} else {
mContent.layout(l - mSidebarWidth, 0, r - mSidebarWidth, b);
}
} else {
mContent.layout(l, 0, r, b);
}
}
#Override
public void onMeasure(int w, int h) {
super.onMeasure(w, h);
super.measureChildren(w, h);
mSidebarWidth = mSidebar.getMeasuredWidth();
}
#Override
protected void measureChild(View child, int parentWSpec, int parentHSpec) {
/* the max width of Sidebar is 90% of Parent */
if (child == mSidebar) {
int mode = MeasureSpec.getMode(parentWSpec);
int width = (int)(getMeasuredWidth() * 0.9);
super.measureChild(child, MeasureSpec.makeMeasureSpec(width, mode), parentHSpec);
} else {
super.measureChild(child, parentWSpec, parentHSpec);
}
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!isOpening()) {
return false;
}
int action = ev.getAction();
if (action != MotionEvent.ACTION_UP
&& action != MotionEvent.ACTION_DOWN) {
return false;
}
/* if user press and release both on Content while
* sidebar is opening, call listener. otherwise, pass
* the event to child. */
int x = (int)ev.getX();
int y = (int)ev.getY();
if (mContent.getLeft() < x
&& mContent.getRight() > x
&& mContent.getTop() < y
&& mContent.getBottom() > y) {
if (action == MotionEvent.ACTION_DOWN) {
mPressed = false;
}
if (mPressed
&& action == MotionEvent.ACTION_UP
&& mListener != null) {
mPressed = false;
return mListener.onContentTouchedWhenOpening();
}
} else {
mPressed = false;
}
return false;
}
public void setListener(Listener l) {
mListener = l;
}
/* to see if the Sidebar is visible */
public boolean isOpening() {
return mOpened;
}
public void toggleSidebar() {
if (mContent.getAnimation() != null) {
return;
}
if (mOpened) {
/* opened, make close animation*/
if (mPlaceLeft) {
mAnimation = new TranslateAnimation(0, -mSidebarWidth, 0, 0);
} else {
mAnimation = new TranslateAnimation(0, mSidebarWidth, 0, 0);
}
mAnimation.setAnimationListener(mCloseListener);
} else {
/* not opened, make open animation */
if (mPlaceLeft) {
mAnimation = new TranslateAnimation(0, mSidebarWidth, 0, 0);
} else {
mAnimation = new TranslateAnimation(0, -mSidebarWidth, 0, 0);
}
mAnimation.setAnimationListener(mOpenListener);
}
mAnimation.setDuration(DURATION);
mAnimation.setFillAfter(true);
mAnimation.setFillEnabled(true);
mContent.startAnimation(mAnimation);
}
public void openSidebar() {
if (!mOpened) {
toggleSidebar();
}
}
public void closeSidebar() {
if (mOpened) {
toggleSidebar();
}
}
class OpenListener implements Animation.AnimationListener {
View iSidebar;
View iContent;
OpenListener(View sidebar, View content) {
iSidebar = sidebar;
iContent = content;
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
iSidebar.setVisibility(View.VISIBLE);
}
public void onAnimationEnd(Animation animation) {
iContent.clearAnimation();
mOpened = !mOpened;
requestLayout();
if (mListener != null) {
mListener.onSidebarOpened();
}
}
}
class CloseListener implements Animation.AnimationListener {
View iSidebar;
View iContent;
CloseListener(View sidebar, View content) {
iSidebar = sidebar;
iContent = content;
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
iContent.clearAnimation();
iSidebar.setVisibility(View.INVISIBLE);
mOpened = !mOpened;
requestLayout();
if (mListener != null) {
mListener.onSidebarClosed();
}
}
}
public interface Listener
{
public void onSidebarOpened();
public void onSidebarClosed();
public boolean onContentTouchedWhenOpening();
}
}
Related
My Issue is that I have a LinearLayout that I am inflating at runtime to a LinearLayout inside ScrollView.
This is the main_activity.xml
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/controlLayoutCV"
android:layout_alignParentStart="true"
android:layout_below="#+id/toolLayoutCV">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/dp5"
android:paddingLeft="#dimen/dp7"
android:paddingRight="#dimen/dp7"
android:paddingTop="#dimen/dp5">
<android.support.v7.widget.CardView
android:id="#+id/questionQuizCV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="#dimen/dp2">
<com.emedicoz.app.CustomViews.JustifiedTextView
android:id="#+id/questionQuizTV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/dp5"
android:text="" />
</android.support.v7.widget.CardView>
<LinearLayout
android:id="#+id/quizQuestionLL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/questionQuizCV"
android:layout_marginTop="#dimen/dp5"
android:orientation="vertical"
android:padding="#dimen/dp5" />
</RelativeLayout>
</ScrollView>
& this is the item_layout.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mcqlayout_LL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="#dimen/dp5"
android:minHeight="30dp"
android:orientation="horizontal"
android:paddingBottom="#dimen/dp7"
android:paddingTop="#dimen/dp7">
<TextView
android:id="#+id/optioniconTV"
android:layout_width="#dimen/dp40"
android:layout_height="#dimen/dp40"
android:background="#drawable/circle_bg"
android:gravity="center"
android:padding="#dimen/dp3"
android:text="A"
android:textSize="#dimen/sub_heading_text_size" />
<com.emedicoz.app.CustomViews.JustifiedTextView
android:id="#+id/optionTextTV"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/dp10" />
</LinearLayout>
This is the CustomTextView that I have created to show the HTML content directly. The JustifiedTextView.class is
public class JustifiedTextView extends WebView {
private String text = "";
private int textSize = 12;
private int backgroundColor = Color.TRANSPARENT;
public JustifiedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setWebChromeClient(new WebChromeClient() {});
}
public void setText(String s) {
this.text = s;
reloadData();
}
#SuppressLint("NewApi")
private void reloadData() {
// loadData(...) has a bug showing utf-8 correctly. That's why we need to set it first.
this.getSettings().setDefaultTextEncodingName("utf-8");
// this.loadData(String.format(core,textColor,textSize,text), "text/html","utf-8");
this.loadData(text, "text/html", "utf-8");
// set WebView's background color *after* data was loaded.
super.setBackgroundColor(backgroundColor);
// Hardware rendering breaks background color to work as expected.
// Need to use software renderer in that case.
if (android.os.Build.VERSION.SDK_INT >= 11)
this.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
public void setTextSize(int textSize) {
this.textSize = textSize;
reloadData();
}
}
I have tried All of the solutions mentioned below.
Disable WebView touch events in Android
Already tried to set the android:descendantFocusability="blocksDescendants" to ScrollView
Why the click Event of LinearLayout does not fire when making click on WebView?
This is the way I am inflating the Layout and handle the click event.
private LinearLayout initAnswerMCViews(String text, String questions, Questions questionsModel) {
LinearLayout view = (LinearLayout) View.inflate(activity, R.layout.mcq_quiz, null);
answerTV = (JustifiedTextView) view.findViewById(R.id.optionTextTV);
optionIconTV = (TextView) view.findViewById(R.id.optioniconTV);
mcqItemLL = (LinearLayout) view.findViewById(R.id.mcqlayout_LL);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
lp.setMargins(3, 3, 3, 3);
mcqItemLL.setLayoutParams(lp);
if (questionsModel.isAnswered()) {
String[] answer = questionsModel.getUser_answer().split(",");
for (int i = 0; i < answer.length; i++) {
if (answer[i].equals(text)) {
answerTV.setText(questions);
optionIconTV.setText(text);
optionIconTV.setBackgroundResource(R.drawable.circle_bg_true);
} else {
answerTV.setText(questions);
optionIconTV.setText(text);
}
}
} else {
answerTV.setText(questions);
optionIconTV.setText(text);
}
mcqItemLL.setTag(R.id.questions, optionIconTV.getText().toString());
mcqItemLL.setTag(R.id.optionsAns, mcqItemLL);
mcqItemLL.setOnClickListener(optionClickListener);
viewArrayList.add(mcqItemLL);
return view;
}
Why the click is not get listen when clicked on the WebView part in the Layout?
I finally found the issue.
It is basically the issue of conflicting Touch Event of both parent Scrollview and CustomWebView.
So, by using the new classes that itself overriding the ClickListener and TouchListener.
package com.app.CustomViews;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
public class TestSeriesOptionWebView extends WebView implements GestureDetector.OnGestureListener {
private boolean check = false;
class LongClick implements OnLongClickListener {
final /* synthetic */ TestSeriesOptionWebView testSeriesOptionWebView;
LongClick(TestSeriesOptionWebView testSeriesOptionWebView) {
this.testSeriesOptionWebView = testSeriesOptionWebView;
}
public boolean onLongClick(View view) {
return true;
}
}
public TestSeriesOptionWebView(Context context) {
super(context);
handleClick();
}
public TestSeriesOptionWebView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
handleClick();
}
public TestSeriesOptionWebView(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
handleClick();
}
private void handleClick() {
setFocusable(false);
/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}*/
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setVerticalScrollBarEnabled(false);
setBackgroundColor(0);
setHapticFeedbackEnabled(false);
setOnLongClickListener(new LongClick(this));
}
public void setDisableWebViewTouchListener(boolean z) {
this.check = z;
}
public boolean onTouchEvent(MotionEvent motionEvent) {
if (this.check) {
return false;
}
return super.onTouchEvent(motionEvent);
}
public boolean canScrollHorizontal(int i) {
int computeHorizontalScrollOffset = computeHorizontalScrollOffset();
int computeHorizontalScrollRange = computeHorizontalScrollRange() - computeHorizontalScrollExtent();
if (computeHorizontalScrollRange == 0) {
return false;
}
if (i < 0) {
if (computeHorizontalScrollOffset <= 0) {
return false;
}
return true;
} else if (computeHorizontalScrollOffset >= computeHorizontalScrollRange - 1) {
return false;
} else {
return true;
}
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
public boolean onDown(MotionEvent motionEvent) {
return true;
}
public void onShowPress(MotionEvent motionEvent) {
}
public boolean onSingleTapUp(MotionEvent motionEvent) {
return false;
}
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent2, float f, float f2) {
return f != 0.0f;
}
public void onLongPress(MotionEvent motionEvent) {
}
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent2, float f, float f2) {
return true;
}
}
If anybody faces this type of issue, then Use this Custom Class TestSeriesOptionWebView.class.
I have a trapezoid shape created in custom view using below code.
#Override
protected void onDraw(Canvas canvas) {
trapezoidPath.moveTo(0,0);
trapezoidPath.lineTo(getWidth() ,0);
trapezoidPath.lineTo(getWidth() , altitude);
trapezoidPath.lineTo(0,getHeight());
trapezoidPath.lineTo(0,0);
trapezoidPath.close();
canvas.drawPath(trapezoidPath,paintTrapezoid);
}
The drawn shape looks like this.
I want to move (0,height) point to top until trapezoid shape become a rectangle. After that I want to move bottom line up until shape become a line.
Is there any way to access created path lines and it's point and manipulate them to achieve what I want ? If not how can I achieve this ?
I have to animate this shape base on user response. Thank you.
Use an ObjectAnimator to change the variables you use in onDraw. Below is an example of how you could implement this.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TrapezoidView trapezoidView = findViewById(R.id.trapezoid);
final Button resetButton = findViewById(R.id.btn_reset);
resetButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
trapezoidView.reset();
}
});
final Button animateButton = findViewById(R.id.btn_animate);
animateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animateButton.setEnabled(false);
resetButton.setEnabled(false);
trapezoidView.toNewState();
}
});
trapezoidView.setListener(new TrapezoidView.TrapezoidListener() {
#Override
public void onNewState() {
animateButton.setEnabled(true);
resetButton.setEnabled(true);
}
});
}
}
TrapezoidView.java
public class TrapezoidView extends View {
public interface TrapezoidListener {
void onNewState();
}
public static final int TRAPEZOID_STATE = 0;
public static final int RECTANGLE_STATE = 1;
public static final int LINE_STATE = 2;
private int mState = TRAPEZOID_STATE;
private Paint mTrapezoidPaint;
private Path mTrapezoidPath = new Path();
private int mAnimationDuration = 5000; // 5 s in millis
private float mRectangleHeight = dpTopx(200);
private float mAltitude = mRectangleHeight;
private TrapezoidListener mListener;
public TrapezoidView(Context context, AttributeSet attrs) {
super(context, attrs);
mTrapezoidPaint = new Paint();
mTrapezoidPaint.setColor(Color.BLACK);
mTrapezoidPaint.setStrokeWidth(5.0f);
mTrapezoidPaint.setStyle(Paint.Style.STROKE);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mTrapezoidPath.reset();
if (mState == TRAPEZOID_STATE) {
mAltitude = getHeight();
}
mTrapezoidPath.moveTo(0, 0);
mTrapezoidPath.lineTo(getWidth(), 0);
if (mState == LINE_STATE) {
mTrapezoidPath.lineTo(getWidth(), mAltitude);
mTrapezoidPath.lineTo(0, mAltitude);
} else {
mTrapezoidPath.lineTo(getWidth(), mRectangleHeight);
mTrapezoidPath.lineTo(0, mAltitude);
}
mTrapezoidPath.lineTo(0, 0);
mTrapezoidPath.close();
canvas.drawPath(mTrapezoidPath, mTrapezoidPaint);
}
private float dpTopx(int dp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
public float getAltitude() {
return mAltitude;
}
public void setAltitude(float altitude) {
this.mAltitude = altitude;
invalidate();
}
public void reset() {
mState = TRAPEZOID_STATE;
mRectangleHeight = dpTopx(200);
mAltitude = mRectangleHeight;
invalidate();
}
public void setListener(TrapezoidListener listener) {
mListener = listener;
}
public void toNewState() {
if (mState == LINE_STATE) {
mListener.onNewState();
return;
}
float start;
float target;
final int targetState = mState == TRAPEZOID_STATE ? RECTANGLE_STATE : LINE_STATE;
if (targetState == RECTANGLE_STATE) {
start = getHeight();
target = mRectangleHeight;
} else {
start = mAltitude;
target = 0.0f;
}
ObjectAnimator stateAnimation = ObjectAnimator.ofFloat(TrapezoidView.this, "Altitude", start);
stateAnimation.setFloatValues(target);
stateAnimation.setDuration(mAnimationDuration);
stateAnimation.addListener(
new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
mState = targetState;
}
#Override
public void onAnimationEnd(Animator animation) {
mListener.onNewState();
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
}
);
stateAnimation.start();
}
}
activity_main.xml
<LinearLayout 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:orientation="vertical"
android:padding="50dp"
tools:context="test.example.MainActivity">
<test.example.TrapezoidView
android:id="#+id/trapezoid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.9" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.1"
android:orientation="horizontal">
<Button
android:id="#+id/btn_animate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Animate!" />
<Button
android:id="#+id/btn_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reset" />
</LinearLayout>
</LinearLayout>
I want develope this rotation in my App . I have implemented the "down" menu ("můj dealer", "moje Volvo", "kontakty") and I need implement the "upper" rotating menu.
How can I do it? Do you have tips? Hope you understand me.
Images (please, watch the video above in the link):
Menu_item_test.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" >
<ImageView
android:id="#+id/menuItemImg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/tab_1_1" />
</RelativeLayout>
Activity_main.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"
tools:context=".MainActivity" >
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/rotationMenu" >
</FrameLayout>
<ImageView
android:id="#+id/imageViewShadow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="60dp"
android:contentDescription="shadow"
android:scaleType="fitXY"
android:src="#drawable/half_round_back" />
<cz.mixedapps.volvista.RotationMenu
android:id="#+id/rotationMenu"
android:layout_width="match_parent"
android:layout_height="265dp"
android:layout_alignParentBottom="true" >
</cz.mixedapps.volvista.RotationMenu>
</RelativeLayout>
I have put together a custom view which replicates the behaviour, you still have to style it like in you example, but it works with an arbitrary number of child views and currently looks like this:
EDIT: I added the ability to show and hide the upper rotating menu with two methods, showRotationMenu() and hideRotationMenu():
Of course there is a lot you can do to improve this view. I just wrote this in 15 minutes and therefor it is a little rough around the edges. But it should be more than enough to put you on the right track. Both the looks of the buttons and of the views which rotate is completely customisable.
1) Source
RotationMenu.java:
import android.content.Context;
import android.content.res.Resources;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.*;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
/**
* Created by Xaver Kapeller on 26/03/14.
*/
public class RotationMenu extends LinearLayout {
private final DataSetObserver dataSetObserver = new DataSetObserver() {
#Override
public void onChanged() {
super.onChanged();
reloadAdapter();
}
};
private RotationMenuAdapter adapter;
private FrameLayout flViewContainer;
private LinearLayout llMenu;
private View currentView;
private View previousView;
private int animationPivotX;
private int animationPivotY;
private int selectedPosition = 0;
public RotationMenu(Context context) {
super(context);
setupMenu();
}
public RotationMenu(Context context, AttributeSet attrs) {
super(context, attrs);
setupMenu();
}
public RotationMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setupMenu();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.animationPivotX = w / 2;
this.animationPivotY = h;
}
private void setupMenu() {
this.setOrientation(VERTICAL);
this.flViewContainer = new FrameLayout(getContext());
this.addView(this.flViewContainer, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dpToPixel(150)));
this.llMenu = new LinearLayout(getContext());
this.llMenu.setOrientation(LinearLayout.HORIZONTAL);
this.addView(this.llMenu, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
}
private int dpToPixel(int dp) {
float scale = getDisplayDensityFactor();
return (int) (dp * scale + 0.5f);
}
private float getDisplayDensityFactor() {
Resources res = getResources();
if (res != null) {
DisplayMetrics metrics = res.getDisplayMetrics();
if(metrics != null) {
return metrics.density;
}
}
return 1.0f;
}
public RotationMenuAdapter getAdapter() {
return this.adapter;
}
public void setAdapter(RotationMenuAdapter adapter) {
if (adapter != null) {
if (this.adapter != null) {
this.adapter.unregisterDataSetObserver(this.dataSetObserver);
}
adapter.registerDataSetObserver(this.dataSetObserver);
this.adapter = adapter;
reloadAdapter();
}
}
public boolean isRotationMenuVisible() {
return this.flViewContainer.getVisibility() == View.VISIBLE;
}
public void showRotationMenu() {
if(this.flViewContainer.getVisibility() != View.VISIBLE) {
this.flViewContainer.setVisibility(View.VISIBLE);
AnimationSet set = new AnimationSet(false);
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1, Animation.RELATIVE_TO_SELF, 0);
translateAnimation.setDuration(1000);
set.addAnimation(translateAnimation);
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(1000);
set.addAnimation(alphaAnimation);
this.flViewContainer.startAnimation(set);
}
}
public void hideRotationMenu() {
if(this.flViewContainer.getVisibility() == View.VISIBLE) {
AnimationSet set = new AnimationSet(false);
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1);
translateAnimation.setDuration(1000);
set.addAnimation(translateAnimation);
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
alphaAnimation.setDuration(1000);
set.addAnimation(alphaAnimation);
set.setAnimationListener(new ViewAnimationEndListener(this.flViewContainer) {
#Override
protected void onAnimationEnd(Animation animation, View view) {
view.setVisibility(View.GONE);
}
});
this.flViewContainer.startAnimation(set);
}
}
private void reloadAdapter() {
Context context = getContext();
if (this.adapter != null && context != null) {
int viewCount = this.adapter.getCount();
int oldViewCount = this.llMenu.getChildCount();
for (int i = 0; i < Math.max(oldViewCount, viewCount); i++) {
if (i < viewCount) {
LayoutParams layoutParams = new LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1);
View menuItem;
if (i < this.llMenu.getChildCount()) {
menuItem = this.adapter.getMenuItemView(i, this.llMenu.getChildAt(i), this.llMenu);
if(menuItem.getParent() == null) {
this.llMenu.removeViewAt(i);
this.llMenu.addView(menuItem, i, layoutParams);
}
} else {
menuItem = this.adapter.getMenuItemView(i, null, this.llMenu);
this.llMenu.addView(menuItem, layoutParams);
}
menuItem.setOnClickListener(new MenuItemClickListener(i));
} else {
this.llMenu.removeViewAt(i);
}
}
this.flViewContainer.removeAllViews();
this.previousView = this.currentView;
if (this.selectedPosition >= viewCount) {
this.selectedPosition = viewCount - 1;
}
this.currentView = this.adapter.getView(this.selectedPosition, this.previousView, this);
addViewWithAnimation(this.currentView, false);
}
}
public void switchToItem(int position, boolean animate) {
if (this.adapter != null) {
int viewCount = this.adapter.getCount();
position = valueInRange(position, 0, viewCount - 1);
if (position != this.selectedPosition) {
View oldView = this.currentView;
this.currentView = this.adapter.getView(position, this.previousView, this);
this.previousView = oldView;
addViewWithAnimation(this.currentView, animate, position < this.selectedPosition);
removeViewWithAnimation(this.previousView, animate, position < this.selectedPosition);
this.selectedPosition = position;
}
}
}
private int valueInRange(int value, int min, int max) {
if (value > max) {
value = max;
} else if (value < min) {
value = min;
}
return value;
}
private void addViewWithAnimation(View view, boolean animate, boolean leftToRight) {
if (view != null) {
if(view.getParent() == null) {
this.flViewContainer.addView(view, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
if (animate) {
int start = leftToRight ? -90 : 90;
Animation rotateIn = new RotateAnimation(start, 0, this.animationPivotX, this.animationPivotY);
rotateIn.setDuration(1000);
view.startAnimation(rotateIn);
}
}
}
private void addViewWithAnimation(View view, boolean animate) {
addViewWithAnimation(view, animate, true);
}
private void removeViewWithAnimation(View view, boolean animate, boolean leftToRight) {
if (view != null) {
if (animate) {
int target = leftToRight ? 90 : -90;
Animation rotateOut = new RotateAnimation(0, target, this.animationPivotX, this.animationPivotY);
rotateOut.setDuration(1000);
rotateOut.setAnimationListener(new ViewAnimationEndListener(view) {
#Override
protected void onAnimationEnd(Animation animation, View view) {
flViewContainer.removeView(view);
}
});
view.startAnimation(rotateOut);
} else {
this.flViewContainer.removeView(view);
}
}
}
private void removeViewWithAnimation(View view, boolean animate) {
removeViewWithAnimation(view, animate, true);
}
private abstract class ViewAnimationEndListener implements Animation.AnimationListener {
private final View view;
private ViewAnimationEndListener(View view) {
this.view = view;
}
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
onAnimationEnd(animation, this.view);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
protected abstract void onAnimationEnd(Animation animation, View view);
}
private class MenuItemClickListener implements OnClickListener {
private final int position;
MenuItemClickListener(int position) {
this.position = position;
}
#Override
public void onClick(View v) {
if(adapter != null && adapter.isMenuItemEnabled(this.position) && isRotationMenuVisible()) {
switchToItem(this.position, true);
}
}
}
}
RotationMenuAdapter.java:
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
/**
* Created by Xaver Kapeller on 26/03/14.
*/
public abstract class RotationMenuAdapter extends BaseAdapter {
public abstract View getMenuItemView(int position, View convertView, ViewGroup parent);
public abstract long getMenuItemId(int position);
public abstract boolean isMenuItemEnabled(int position);
}
2) Usage:
The custom view is making use of adapters and view recycling, so you use it the same way you would use a ListView. Because of the view recycling it is not very memory intensive and actually pretty fast. The logic for the creating of the menu items at the bottom is also in the adapter and it too uses view recycling. So be sure that you implement getMenuItemView() with the same care you would use to implement getView(). First you have to write an adapter:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import at.test.app.R;
import at.test.app.RotationMenu.RotationMenuAdapter;
import java.util.List;
/**
* Created by Xaver Kapeller on 26/03/14.
*/
public class TestAdapter extends RotationMenuAdapter {
private static final long TEST_VIEW_ID = 0;
private static final long DEFAULT_VIEW_ID = TEST_VIEW_ID;
private static final long TEST_MENU_ID = 0;
private static final long DEFAULT_MENU_ID = TEST_MENU_ID;
private final LayoutInflater inflater;
private final List<TestViewModel> viewModels;
public TestAdapter(Context context, List<TestViewModel> viewModels) {
this.inflater = LayoutInflater.from(context);
this.viewModels = viewModels;
}
#Override
public int getCount() {
return this.viewModels.size();
}
#Override
public Object getItem(int position) {
return this.viewModels.get(position);
}
#Override
public long getItemId(int position) {
Object viewModel = getItem(position);
if(viewModel instanceof TestViewModel) {
return TEST_VIEW_ID;
}
return DEFAULT_VIEW_ID;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(getItemId(position) == TEST_VIEW_ID) {
TestViewModel viewModel = (TestViewModel) getItem(position);
TestRow row;
if(convertView == null) {
convertView = this.inflater.inflate(TestRow.LAYOUT, parent, false);
row = new TestRow(convertView);
convertView.setTag(row);
}
row = (TestRow) convertView.getTag();
row.bind(viewModel);
}
return convertView;
}
#Override
public View getMenuItemView(int position, View convertView, ViewGroup parent) {
if(getMenuItemId(position) == TEST_MENU_ID) {
TestViewModel viewModel = (TestViewModel)getItem(position);
MenuRow row;
if(convertView == null) {
convertView = this.inflater.inflate(MenuRow.LAYOUT, parent, false);
row = new MenuRow(convertView);
convertView.setTag(row);
}
row = (MenuRow)convertView.getTag();
row.bind(viewModel);
}
return convertView;
}
#Override
public long getMenuItemId(int position) {
Object item = getItem(position);
if(item instanceof TestViewModel) {
return TEST_MENU_ID;
}
return DEFAULT_MENU_ID;
}
#Override
public boolean isMenuItemEnabled(int position) {
return true;
}
}
Nothing special, except the extra methods for the creating of the menu items. In isMenuItemEnabled() you can add logic to enable/disable menu items if you need to.
And then you apply your adapter to the view:
List<TestViewModel> viewModels = new ArrayList<TestViewModel>();
TestViewModel menuItemOne = new TestViewModel();
menuItemOne.setMenuItemIconResId(R.drawable.icon);
viewModels.add(menuItemOne);
TestViewModel menuItemTwo = new TestViewModel();
menuItemTwo.setMenuItemIconResId(R.drawable.icon);
viewModels.add(menuItemTwo);
TestAdapter adapter = new TestAdapter(getActivity(), viewModels);
this.rotationMenu.setAdapter(adapter);
EDIT:
Try this layout with wrap_content instead match_parent:
<?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" >
<ImageView
android:id="#+id/menuItemImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#drawable/tab_1_1" />
</RelativeLayout>
I'm also no so sure about your layout_width, are you sure you need match_parent there? I don't think so.
i want to create one screen for my android application in this application i want to create sliding navigation feature which is full visible on swipe (Left to Right ) and when user again swipe (RIght to Left ) it again swipe and close navigation window half and display half screen , i have used navigation drawer but i am not aware with this so please some help me if you have any code so please send me its will be my pleasure .
i am sending one image for reference where .
Find below code create a class AnimationLayout
import usb.terminal.R;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
public class AnimationLayout extends ViewGroup {
public final static int DURATION = 1000;
protected boolean mPlaceLeft = true;
public boolean mOpened;
protected View mSidebar;
protected View mContent;
protected int mSidebarWidth = 100; /*
* assign default value. It will be
* overwrite in onMeasure by Layout xml
* resource.
*/
protected Animation mAnimation;
protected OpenListener mOpenListener;
protected CloseListener mCloseListener;
protected Listener mListener;
protected boolean mPressed = false;
public AnimationLayout(Context context) {
this(context, null);
}
public AnimationLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void onFinishInflate() {
super.onFinishInflate();
mSidebar = findViewById(R.id.animation_layout_sidebar);
mContent = findViewById(R.id.animation_layout_content);
if (mSidebar == null) {
throw new NullPointerException("no view id = animation_sidebar");
}
if (mContent == null) {
throw new NullPointerException("no view id = animation_content");
}
mOpenListener = new OpenListener(mSidebar, mContent);
mCloseListener = new CloseListener(mSidebar, mContent);
}
#Override
public void onLayout(boolean changed, int l, int t, int r, int b) {
/* the title bar assign top padding, drop it */
int sidebarLeft = l;
if (!mPlaceLeft) {
sidebarLeft = r - mSidebarWidth;
}
mSidebar.layout(sidebarLeft, 0, sidebarLeft + mSidebarWidth,
0 + mSidebar.getMeasuredHeight());
if (mOpened) {
if (mPlaceLeft) {
mContent.layout(l + mSidebarWidth, 0, r + mSidebarWidth, b);
} else {
mContent.layout(l - mSidebarWidth, 0, r - mSidebarWidth, b);
}
} else {
mContent.layout(l, 0, r, b);
}
}
#Override
public void onMeasure(int w, int h) {
super.onMeasure(w, h);
super.measureChildren(w, h);
mSidebarWidth = mSidebar.getMeasuredWidth();
}
#Override
protected void measureChild(View child, int parentWSpec, int parentHSpec) {
/* the max width of Sidebar is 90% of Parent */
if (child == mSidebar) {
int mode = MeasureSpec.getMode(parentWSpec);
int width = (int) (getMeasuredWidth() * 0.9);
super.measureChild(child, MeasureSpec.makeMeasureSpec(width, mode),
parentHSpec);
} else {
super.measureChild(child, parentWSpec, parentHSpec);
}
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!isOpening()) {
return false;
}
int action = ev.getAction();
if (action != MotionEvent.ACTION_UP
&& action != MotionEvent.ACTION_DOWN) {
return false;
}
/*
* if user press and release both on Content while sidebar is opening,
* call listener. otherwise, pass the event to child.
*/
int x = (int) ev.getX();
int y = (int) ev.getY();
if (mContent.getLeft() < x && mContent.getRight() > x
&& mContent.getTop() < y && mContent.getBottom() > y) {
if (action == MotionEvent.ACTION_DOWN) {
mPressed = true;
}
if (mPressed && action == MotionEvent.ACTION_UP
&& mListener != null) {
mPressed = false;
return mListener.onContentTouchedWhenOpening();
}
} else {
mPressed = false;
}
return false;
}
public void setListener(Listener l) {
mListener = l;
}
/* to see if the Sidebar is visible */
public boolean isOpening() {
return mOpened;
}
public void toggleSidebar() {
if (mContent.getAnimation() != null) {
return;
}
if (mOpened) {
/* opened, make close animation */
if (mPlaceLeft) {
mAnimation = new TranslateAnimation(0, -mSidebarWidth, 0, 0);
} else {
mAnimation = new TranslateAnimation(0, mSidebarWidth, 0, 0);
}
mAnimation.setAnimationListener(mCloseListener);
} else {
/* not opened, make open animation */
if (mPlaceLeft) {
mAnimation = new TranslateAnimation(0, mSidebarWidth, 0, 0);
} else {
mAnimation = new TranslateAnimation(0, -mSidebarWidth, 0, 0);
}
mAnimation.setAnimationListener(mOpenListener);
}
mAnimation.setDuration(DURATION);
mAnimation.setFillAfter(true);
mAnimation.setFillEnabled(true);
mContent.startAnimation(mAnimation);
}
public void openSidebar() {
if (!mOpened) {
toggleSidebar();
}
}
public void closeSidebar() {
if (mOpened) {
toggleSidebar();
}
}
class OpenListener implements Animation.AnimationListener {
View iSidebar;
View iContent;
OpenListener(View sidebar, View content) {
iSidebar = sidebar;
iContent = content;
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
iSidebar.setVisibility(View.VISIBLE);
}
public void onAnimationEnd(Animation animation) {
iContent.clearAnimation();
mOpened = !mOpened;
requestLayout();
if (mListener != null) {
mListener.onSidebarOpened();
}
}
}
class CloseListener implements Animation.AnimationListener {
View iSidebar;
View iContent;
CloseListener(View sidebar, View content) {
iSidebar = sidebar;
iContent = content;
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
iContent.clearAnimation();
iSidebar.setVisibility(View.INVISIBLE);
mOpened = !mOpened;
requestLayout();
if (mListener != null) {
mListener.onSidebarClosed();
}
}
}
public interface Listener {
public void onSidebarOpened();
public void onSidebarClosed();
public boolean onContentTouchedWhenOpening();
}
}
create a mainlayout.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" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<yourpackage..AnimationLayout
android:id="#+id/animation_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!--Create you Layout which you want and just call in this include-->
<include
android:id="#id/animation_layout_sidebar"
android:layout_width="470dp"
android:layout_height="match_parent"
layout="#layout/my_cook_menu"
android:orientation="vertical" >
</include>
<!--Create you Layout which you want and just call in this include-->
<include
android:id="#id/animation_layout_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="#layout/sound_my_cook"
android:clickable="true"
android:focusable="true"
android:orientation="vertical" >
</include>
</yourpackage.AnimationLayout>
</RelativeLayout>
</RelativeLayout>
create id.xml in values folder
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="animation_layout_sidebar" />
<item type="id" name="animation_layout_content" />
</resources>
write this code in which activity you are calling
public class MainActivity extends Activity implements
AnimationLayout.Listener, OnClickListener{
AnimationDrawable frameAnimation;
AnimationLayout animationLayout;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlayout);
}
public void onClick(View v) {
try {
animationLayout = (AnimationLayout) findViewById(R.id.animation_layout);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
animationLayout.toggleSidebar();
}
#Override
public void onSidebarOpened() {
// TODO Auto-generated method stub
}
#Override
public void onSidebarClosed() {
// TODO Auto-generated method stub
}
#Override
public boolean onContentTouchedWhenOpening() {
// TODO Auto-generated method stub
return false;
}
}
I haven't tried it yet but I think DrawerLayout recently added to support library could give you what you need. Here is the link for documentation. This is something what Facebook app is using to slide a pannel from left to right. Here is the tutorial.
In my Android application, I have to use a custom number-pad which is placed in view next to EditTexts to input numbers, so I need:
EditText should have focus when user tap them so that I will have cursor position to insert number when user hits a key.
Soft Keyboard should not appear when edit text is focused (but cannot hide keyboard completely by setting android:windowSoftInputMode="stateHidden" because there is a some search box in the screen still need to use soft keyboard)
I have searched and found many articles about hiding keyboard programmingly when it is being shown, or set input type/focusable....to not show keyboard....but they are not meet my need.
Anybody have solution for this case please help me.
This one i took inspiration from CsipSimple Project and implemented my own
Here is the code for the same
Create a Custom NumberPad here is mine
the layout for dialpad is just buttons from 1 to 9 and * an #
package com.xyz.custom;
import java.util.HashMap;
import java.util.Map;
import com.xyz.payphone.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.media.ToneGenerator;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.widget.ImageButton;
import android.widget.TableLayout;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
public class DialpadNovanet extends TableLayout implements OnClickListener {
private OnDialKeyListener onDialKeyListener;
#SuppressLint("UseSparseArrays")
private static final Map<Integer, int[]> DIGITS_BTNS = new HashMap<Integer, int[]>();
private static final String tag = "Dialpad";
static {
DIGITS_BTNS.put(R.id.button0, new int[] { ToneGenerator.TONE_DTMF_0,
KeyEvent.KEYCODE_0 });
DIGITS_BTNS.put(R.id.button1, new int[] { ToneGenerator.TONE_DTMF_1,
KeyEvent.KEYCODE_1 });
DIGITS_BTNS.put(R.id.button2, new int[] { ToneGenerator.TONE_DTMF_2,
KeyEvent.KEYCODE_2 });
DIGITS_BTNS.put(R.id.button3, new int[] { ToneGenerator.TONE_DTMF_3,
KeyEvent.KEYCODE_3 });
DIGITS_BTNS.put(R.id.button4, new int[] { ToneGenerator.TONE_DTMF_4,
KeyEvent.KEYCODE_4 });
DIGITS_BTNS.put(R.id.button5, new int[] { ToneGenerator.TONE_DTMF_5,
KeyEvent.KEYCODE_5 });
DIGITS_BTNS.put(R.id.button6, new int[] { ToneGenerator.TONE_DTMF_6,
KeyEvent.KEYCODE_6 });
DIGITS_BTNS.put(R.id.button7, new int[] { ToneGenerator.TONE_DTMF_7,
KeyEvent.KEYCODE_7 });
DIGITS_BTNS.put(R.id.button8, new int[] { ToneGenerator.TONE_DTMF_8,
KeyEvent.KEYCODE_8 });
DIGITS_BTNS.put(R.id.button9, new int[] { ToneGenerator.TONE_DTMF_9,
KeyEvent.KEYCODE_9 });
DIGITS_BTNS.put(R.id.buttonpound, new int[] {
ToneGenerator.TONE_DTMF_P, KeyEvent.KEYCODE_POUND });
DIGITS_BTNS.put(R.id.buttonstar, new int[] { ToneGenerator.TONE_DTMF_S,
KeyEvent.KEYCODE_STAR });
};
private static final SparseArray<String> DIGITS_NAMES = new SparseArray<String>();
static {
DIGITS_NAMES.put(R.id.button0, "0");
DIGITS_NAMES.put(R.id.button1, "1");
DIGITS_NAMES.put(R.id.button2, "2");
DIGITS_NAMES.put(R.id.button3, "3");
DIGITS_NAMES.put(R.id.button4, "4");
DIGITS_NAMES.put(R.id.button5, "5");
DIGITS_NAMES.put(R.id.button6, "6");
DIGITS_NAMES.put(R.id.button7, "7");
DIGITS_NAMES.put(R.id.button8, "8");
DIGITS_NAMES.put(R.id.button9, "9");
DIGITS_NAMES.put(R.id.buttonpound, "pound");
DIGITS_NAMES.put(R.id.buttonstar, "star");
};
public DialpadNovanet(Context context) {
super(context);
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.dialpad_novanet, this, true);
}
public DialpadNovanet(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.dialpad_novanet, this, true);
}
private void dispatchDialKeyEvent(int buttonId) {
if (onDialKeyListener != null && DIGITS_BTNS.containsKey(buttonId)) {
int[] datas = DIGITS_BTNS.get(buttonId);
onDialKeyListener.onTrigger(datas[1], datas[0]);
}
}
#Override
public void onClick(View v) {
dispatchDialKeyEvent(v.getId());
}
public void setOnDialKeyListener(OnDialKeyListener listener) {
onDialKeyListener = listener;
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
for (int buttonId : DIGITS_BTNS.keySet()) {
ImageButton button = (ImageButton) findViewById(buttonId);
if (button != null) {
button.setOnClickListener(this);
}
}
}
public interface OnDialKeyListener {
/**
* Called when the user make an action
*
* #param keyCode
* keyCode pressed
* #param dialTone
* corresponding dialtone
*/
void onTrigger(int keyCode, int dialTone);
}
boolean mForceWidth = false;
public void setForceWidth(boolean forceWidth) {
mForceWidth = forceWidth;
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mForceWidth) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
getMeasuredHeight());
}
};
/*
* public void applyTheme(Theme t) {
*
* Log.d(tag, "Theming in progress"); for(int buttonId :
* DIGITS_BTNS.keySet()) {
*
* ImageButton b = (ImageButton) findViewById(buttonId); // We need to use
* state list as reused t.applyBackgroundStateListDrawable(b, "btn_dial");
*
* // Src of button Drawable src =
* t.getDrawableResource("dial_num_"+DIGITS_NAMES.get(buttonId)); if(src !=
* null) { b.setImageDrawable(src); }
*
* // Padding of button t.applyLayoutMargin(b, "dialpad_btn_margin"); }
*
* }
*/
}
Now Create Custom EditText
public class DialerEditText extends EditText {
private static final String tag="DialerEditText";
private Boolean isDigit=null;
private Method showSoftInputOnFocus=null;
public DialerEditText(Context context, AttributeSet attrs) {
super(context, attrs);
setIsDigit(true, false);
}
public synchronized void setIsDigit(boolean isDigit, boolean autofocus) {
if(this.isDigit == null || this.isDigit != isDigit) {
this.isDigit = isDigit;
reflexSetShowSoftInputOnFocus(!isDigit);
if (isDigit) {
setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
setTextSize(TypedValue.COMPLEX_UNIT_PX, getContext().getResources().getDimension(R.dimen.dialpad_digits_text_size));
} else {
setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
| InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
}
}
applyKeyboardShowHide(autofocus);
}
#Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if(focused) {
applyKeyboardShowHide(false);
}else {
final InputMethodManager imm = ((InputMethodManager) getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE));
if(imm != null && imm.isActive(this)) {
imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
final boolean ret = super.onTouchEvent(event);
// Must be done after super.onTouchEvent()
applyKeyboardShowHide(false);
return ret;
}
/*
#Override
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
boolean ret = false;
if(!isDigit) {
ret = super.requestFocus(direction, previouslyFocusedRect);
}
applyKeyboardShowHide(false);
return ret;
}
*/
private void applyKeyboardShowHide(boolean autofocus) {
final InputMethodManager imm = ((InputMethodManager) getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE));
if (imm != null) {
if(isDigit) {
if(imm.isActive(this)) {
imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
}
}else if(autofocus) {
imm.showSoftInput(this, 0);
}
}
}
#Override
public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) {
// Since we're replacing the text every time we add or remove a
// character, only read the difference. (issue 5337550)
final int added = event.getAddedCount();
final int removed = event.getRemovedCount();
final int length = event.getBeforeText().length();
if (added > removed) {
event.setRemovedCount(0);
event.setAddedCount(1);
event.setFromIndex(length);
} else if (removed > added) {
event.setRemovedCount(1);
event.setAddedCount(0);
event.setFromIndex(length - 1);
} else {
return;
}
} else if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
// The parent EditText class lets tts read "edit box" when this View
// has a focus, which
// confuses users on app launch (issue 5275935).
return;
}
super.sendAccessibilityEventUnchecked(event);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
// Here we ensure that we hide the keyboard
// Since this will be fired when virtual keyboard this will probably
// blink but for now no better way were found to hide keyboard for sure
applyKeyboardShowHide(false);
}
private void reflexSetShowSoftInputOnFocus(boolean show) {
if(showSoftInputOnFocus != null) {
UtilityWrapper.safelyInvokeMethod(showSoftInputOnFocus, this, show);
}
}
}
Now you can use this as xml Avoid the padding and stuff cause thats my app specific
<LinearLayout 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:orientation="vertical" >
<com.novanet.custom.DialerEditText
android:id="#+id/edtDialer"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="70" />
<com.novanet.custom.DialpadNovanet
android:id="#+id/dial_pad"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="center_vertical"
android:layout_weight="65"
android:paddingBottom="10dip"
android:paddingLeft="5dip"
android:paddingRight="5dip" />
</LinearLayout>
Now in your activity u can do this
edtText=(DialerEditText)findViewById(R.id.edtDialer);
dialPad=(DialpadNovanet)findViewById(R.id.dial_pad);
dialPad.setOnDialKeyListener(new OnDialKeyListener() {
#Override
public void onTrigger(int keyCode, int dialTone) {
Log.v(tag,"Key "+keyCode);
KeyEvent event=new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
edtText.onKeyDown(keyCode, event);
}
});
In the manifest file, in your activity tag have to write a attribute like
android:windowSoftInputMode="stateHidden"
then it hide the keyboard until press the edittext...
in my case i used like this in activity tag to hide softkeyboard until press a edittext...
<activity
android:name="EnglishRadioActivity"
android:configChanges="orientation"
android:windowSoftInputMode="stateHidden" >
</activity>
hope this will solved your problem
happy coding...
useandroid:windowSoftInputMode="stateHidden"
or android:windowSoftInputMode="adjustPan"
android:windowSoftInputMode="stateHidden|adjustPan"
add this in your manifest file after the corresponding Activity name. This will restrict the default Soft Keyboard from appearing in your screen.