i have this sample and i am trying to Implement a Click on item(s) inside sub view
i have this two xml files
this is the subview.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/textLabel"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:textSize="50dip"
android:textColor="#00FF00"
android:textStyle="bold"/>
</LinearLayout>
this is the scrollview.xml view:
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none">
<LinearLayout
android:layout_width="fill_parent"
android:id="#+id/scrollviewlinearlayout"
android:layout_height="fill_parent">
</LinearLayout>
</HorizontalScrollView>
and this is the Activity:
public class TestTwo extends Activity {
Context mContext;
HorizontalScrollView mScrollView;
LinearLayout mLinearLayout;
LinearLayout.LayoutParams mLinearLayoutParams;
Display mDisplay;
// scroll behaviour
private int mScrollStartPosition;
private static final float SCROLL_MARGIN = 0.2f;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
// load layout from xml and get references to sub-views
setContentView(R.layout.scrollview);
mScrollView = (HorizontalScrollView) findViewById(R.id.scrollview);
mLinearLayout = (LinearLayout) findViewById(R.id.scrollviewlinearlayout);
// get a display reference (used to find screen size)
mDisplay = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
// get the layout parameters to apply to the sub-views
mLinearLayoutParams = new LayoutParams(mDisplay.getWidth(), mDisplay.getHeight());
// add some views to the ScrollView
addViewsToScrollView();
}
private void addViewsToScrollView() {
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < 3; i++) {
// inflate view from xml
View child = inflater.inflate(R.layout.subview, null);
// give it a number
final TextView text = (TextView) child.findViewById(R.id.textLabel);
text.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
text.setText("Test");
}
});
text.setText("" + (i + 1));
// give it a colour
text.setBackgroundColor(Color.rgb((int) (Math.random() * 255), (int) (Math.random() * 255),
(int) (Math.random() * 255)));
// apply layout parameters, and add it
child.setLayoutParams(mLinearLayoutParams);
mLinearLayout.addView(child);
}
}
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int viewWidth = mDisplay.getWidth(); // width of each view
int triggerWidth = (int) (SCROLL_MARGIN * viewWidth); // amount user has to scroll to move to next view
int pos = mScrollView.getScrollX();
int diff = pos % viewWidth; // offset of current scroll from leftmost view's snap position
int posLeftView = pos - diff; // absolute snap position of the leftmost view on screen
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// Record the starting scroll position. This is used to decide the scroll direction.
mScrollStartPosition = pos;
break;
case MotionEvent.ACTION_UP:
if (pos > mScrollStartPosition) {
// Scrolling right
if (diff > triggerWidth) mScrollView.smoothScrollTo(posLeftView + viewWidth, 0);
else mScrollView.smoothScrollTo(posLeftView, 0);
} else {
// Scrolling left
if (diff > (viewWidth - triggerWidth)) mScrollView.smoothScrollTo(posLeftView + viewWidth, 0);
else mScrollView.smoothScrollTo(posLeftView, 0);
}
// replacing our scrollTo command with it's own
return true;
}
return super.dispatchTouchEvent(ev);
}
}
i tried to debug it and it seems its not fire the onClick event
can you help me please with this problem ?
You're doing a bunch of wild things that I'll leave for another time. Try text.setClickable(true) on your final TextView text
Ok sorry for all these edits. here are your problems though.
you shouldn't use the child statement
2. you shouldn't be setting an onclick listener for an item thats not within the current content
So......
final TextView text = (TextView) child.findViewById(R.id.textLabel);
should be
final TextView text = (TextView) findViewById(R.id.textLabel);
since the content needs to be set to the proper xml file
setContentView(R.layout.scrollview);
would need to be
setContentView(R.layout.<NAME OF SECOND XML FILE WHICH U DIDNT INCLUDE>);
Related
I am making a productivity app with events that are represented as buttons holding basic information about the event.
The button is contained in a RelativeLayout alongside TextViews, an options menu and a switch. The parent layout's height is set to WRAP_CONTENT. It looks like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="#+id/event_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="#+id/relativeLayout"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="2dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:minHeight="130dp"
android:elevation="0dp"
android:textSize="#dimen/event_item_title_fontSize"
android:visibility="visible"
/>
<include
android:id="#+id/relativeLayout"
layout="#layout/_event_layout_content"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</include> </RelativeLayout>
You can click the button to expand it and show additional information. The expand animation is achieved using a custom animation which updates the button's getLayoutParams().height and calls getParent().requestLayout() every time applyTransformation(...) is called. This works well on an API level 19 (KitKat) device.
Animation code:
//The current state of the button which gets updated on animation finish
boolean expanded = false;
#Override
public void onClick(final View v) {
//Getting references to views
final RelativeLayout layout = (RelativeLayout) button.getParent();
final View separator = layout.findViewById(R.id.separator), list =
layout.findViewById(R.id.notes_list);
final Button button = (Button) v;
final RelativeLayout content = (RelativeLayout) layout.findViewById(R.id.relativeLayout);
final RelativeLayout.LayoutParams lpl = (RelativeLayout.LayoutParams) list.getLayoutParams(),
lpsw = (RelativeLayout.LayoutParams) layout.findViewById(R.id.event_switch).getLayoutParams(),
lp = (RelativeLayout.LayoutParams) button.getLayoutParams();
//Finished getting references to views
final int startHeight = lp.height = button.getHeight();
//Prevents button from automatically resizing to fit its parent when requestLayout is called
lp.removeRule(RelativeLayout.ALIGN_BOTTOM);
layout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) {
layout.removeOnLayoutChangeListener(this);
final int goalHeight = GetExpectedHeight(expanded);
Animation animation = new Animation() {
float alpha1 = (expanded ? startHeight : goalHeight) - separator.getTop(),
alpha2 = (expanded ? startHeight : goalHeight) - list.getTop();
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime < 1) {
//Updates the button's height
lp.height = (int) (startHeight + (goalHeight - startHeight) * interpolatedTime);
separator.setAlpha((lp.height - separator.getTop()) / alpha1);
list.setAlpha((lp.height - list.getTop()) / alpha2);
list.setScaleX(list.getAlpha());
list.setScaleY(list.getAlpha());
layout.requestLayout();
return;
}
//Animation finish
if (expanded) {
separator.setVisibility(View.GONE);
list.setVisibility(View.GONE);
}
lp.height = lp.MATCH_PARENT;
lp.addRule(RelativeLayout.ALIGN_BOTTOM, R.id.relativeLayout);
//A custom method that basically requests layout for whole activity
instance.get().Invalidate();
expanded = !expanded;
this.cancel();
}
};
animation.setInterpolator(new DecelerateInterpolator());
animation.setDuration(400);
layout.startAnimation(animation);
}
});
float alpha = expanded ? 1 : 0;
separator.setAlpha(alpha);
list.setAlpha(alpha);
//Kicks off the onLayoutChange method above
if (!expanded) {
separator.setVisibility(View.VISIBLE);
list.setVisibility(View.VISIBLE);
}
else
layout.requestLayout();
}
However, on an Android 7.0 Nougat (API 24), there is an accompanying ripple effect which overlays the button with a rectangle that doesn't update its height to match the button's height during the animation. I don't know what it looks like on other Android versions because those are the only two devices I can test on. Is there a way to update the ripple effect's rectangle to scale with the button? I would prefer to keep the ripple effect if at all possible. So far I have tried calling performClick() on the button each frame of the animation but to no avail.
Here is a screenshot of the button during expand animation:
And a video of the animation:
https://streamable.com/vehf3
I'm creating a chat application, on launch it displays the twenty most recent messages in a conversation. When you scroll to the top you can press a button to display earlier messages. Pretty typical. The only problem is, I want the UI elements to maintain their position after pressing the button. At the moment they shift. I've created a stripped out version of the problem I'm having.
Before pressing the button
After pressing the button
As you might have guessed, I would like it so that after I press the button the TextView with the label 51 (TextView-51) appears as if it hasn't moved. My original plan was to get the position of TextVie-51 before the button press, and then after the button press, and set the ScrollView's Y position. However that approach doesn't work because the at the time I was checking the View hadn't inflated yet.
Here's the layout xml
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/TestScroller">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:id="#+id/mainContainer" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/TestButton"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:onClick="insertMore"
android:text="Get Earlier Messages" />
</RelativeLayout>
</ScrollView>
Here's the code for the activity.
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.test);
lastId = R.id.TestButton;
firstId = -1;
RelativeLayout rl = (RelativeLayout)findViewById(R.id.mainContainer);
//1. Create fifty TextViews and put them under the button.
for (int i = 51; i <= 100; i++)
{
TextView tv = new TextView(this);
tv.setText(Integer.toString(i));
tv.setId(i + 100);
final int WC = RelativeLayout.LayoutParams.WRAP_CONTENT;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(WC, WC);
params.addRule(RelativeLayout.BELOW, lastId);
tv.setLayoutParams(params);
lastId = tv.getId();
if (firstId == -1)
firstId = tv.getId();
rl.addView(tv);
}
}
public void insertMore(View view)
{
//Create fifty more TextViews and insert them between the button and
//the already created textviews.
RelativeLayout rl = (RelativeLayout)findViewById(R.id.mainContainer);
lastId = R.id.TestButton;
for (int i = 0; i <= 50; i++)
{
TextView tv = new TextView(this);
tv.setText(Integer.toString(i));
tv.setId(i + 100);
final int WC = RelativeLayout.LayoutParams.WRAP_CONTENT;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(WC, WC);
params.addRule(RelativeLayout.BELOW, lastId);
tv.setLayoutParams(params);
lastId = tv.getId();
rl.addView(tv);
}
//Now make sure the textview with the label 51 under it is underneath the last
//view we just added.
TextView tv = (TextView)findViewById(firstId);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)tv.getLayoutParams();
params.addRule(RelativeLayout.BELOW, lastId);
tv.setLayoutParams(params);
//Remove the button
Button button = (Button)findViewById(R.id.TestButton);
rl.removeView(button);
}
Based on your first idea which was to scroll to the bottom of the list after adding textviews, did you try to call requestLayout() to force layout update :
public void insertMore(View view)
{
// Create and add your 50 views
...
// force Update layout
rl.requestLayout();
scrollView.post(new Runnable() {
#Override
public void run() {
// Scroll to scrollviews bottom
scrollView.scrollTo(0, scrollView.getBottom());
}
});
}
I am working on project . I need the width & Height of a LinearLayout from Activity using programming code. This Linear Layout has fixed width and Height . But when i use the following ..i am getting Nullpointer Exception
LinearLayout viewGroup = (LinearLayout) context.findViewById(R.id.popup);
Log.e("getWidth",""+viewGroup.getWidth());
Log.e("getHeight",""+viewGroup.getHeight());
I need the width and height of that layout from activity.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/popup"
android:layout_width="150dp"
android:layout_height="252dp"
android:background="#303030"
android:orientation="vertical" >
</LinearLayout>
Here is the Java code file
public class MainActivity extends Activity {
//The "x" and "y" position of the "Show Button" on screen.
Point p;
Button btn_show;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_show = (Button) findViewById(R.id.show_popup);
}
#Override
protected void onResume() {
super.onResume();
btn_show.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
//Open popup window
if (p != null)
showPopup( p);
}
});
}
// Get the x and y position after the button is draw on screen
// (It's important to note that we can't get the position in the onCreate(),
// because at that stage most probably the view isn't drawn yet, so it will return (0, 0))
#Override
public void onWindowFocusChanged(boolean hasFocus) {
int[] location = new int[2];
Button button = (Button) findViewById(R.id.show_popup);
// Get the x, y location and store it in the location[] array
// location[0] = x, location[1] = y.
button.getLocationOnScreen(location);
//Initialize the Point with x, and y positions
p = new Point();
p.x = location[0];
p.y = location[1];
}
// The method that displays the popup.
private void showPopup( Point p) {
int popupWidth = 200;
int popupHeight = 380;
// Inflate the popup_layout.xml
LinearLayout viewGroup = (LinearLayout) findViewById(R.id.popup);
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = layoutInflater.inflate(R.layout.a, viewGroup);
Log.e("getWidth",""+viewGroup.getWidth());
Log.e("getHeight",""+viewGroup.getHeight());
// Creating the PopupWindow
final PopupWindow popup = new PopupWindow(getApplicationContext());
popup.setContentView(layout);
popup.setWidth(viewGroup.getWidth());
popup.setHeight(viewGroup.getHeight());
popup.setFocusable(true);
// Some offset to align the popup a bit to the right, and a bit down, relative to button's position.
int OFFSET_X = 30;
int OFFSET_Y = 30;
// Clear the default translucent background
popup.setBackgroundDrawable(new BitmapDrawable());
// Displaying the popup at the specified location, + offsets.
popup.showAtLocation(layout, Gravity.NO_GRAVITY, p.x + OFFSET_X, p.y + OFFSET_Y);
// Getting a reference to Close button, and close the popup when clicked.
// Button close = (Button) layout.findViewById(R.id.close);
/* close.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
popup.dismiss();
}
});*/
}
}
It may be that this ViewGroup hasn't been created yet.
Check where you're trying to get the width and height of this object is actually being called after display objects such as views etc are being created. You can debug this by either placing breakpoints in the different loading methods such as onCreate, onResume or by placing NSLog's in them instead.
Only once the method View.onSizeChanged() has been called for the first can you reliably use the getHeight() and getWidth() methods. This means you will have to change the logic of your app to take into account this fact.
You are inflating the layout just to get the width and height, aren't you? If so you don't need the viewGroup. Assuming R.layout.popup_layout points to a LinearLayout that has fixed dimensions:
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout layout = layoutInflater.inflate(R.layout.popup_layout, null);
LayoutParams params = layout.getLayoutParams();
Log.e("getWidth",""+params.width);
Log.e("getHeight",""+params.height);
After that you can set your popup:
final PopupWindow popup = new PopupWindow(getApplicationContext());
popup.setContentView(layout);
popup.setWidth(params.width);
popup.setHeight(params.height);
popup.setFocusable(true);
to wait for the views to be attached and placed in the layout you should useViewTreeObserver.OnGlobalLayoutListener.
you can register it like this:
v.getViewTreeObserver().addOnGlobalLayoutListener( new
OnGlobalLayoutListener() {
public void onGlobalLayout() {
//TODO: do your stuff here
//if you change something in the layout you have to add this
//line to avoid loops
v.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
in that callback you can be sure to have the views with a consistence position and dimension.
I need to set the child view as center of the ViewPager and also I would like to show some part of the next and previous views to the current view sides(like current screen below 1). But currently the current view is starting at left side of the ViewPager(like expected screen below 2). How can I achieve that?
Here is my code..
MyViewPagerAdapter
public class MyViewPagerAdapter extends PagerAdapter {
private Activity mActivity;
private int mPageCount;
public MyViewPagerAdapter(Activity activity,int pageCount) {
mActivity = activity;
mPageCount = pageCount;
}
#Override
public int getCount() {
return mPageCount;
}
#Override
public boolean isViewFromObject(View view, Object obj) {
return (view ==(View)obj);
}
#Override
public Object instantiateItem(ViewGroup container,final int position) {
ViewGroup viewGroup = (ViewGroup)mActivity.getLayoutInflater().inflate(
R.layout.item_view, null);
viewGroup.setBackgroundColor(randomColor());
TextView textView = (TextView)viewGroup.findViewById(R.id.textView1);
textView.setText("Page: "+(position+1));
Button button = (Button) viewGroup.findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mActivity, "Hey, Its clicked!!! at page "+(position+1), Toast.LENGTH_LONG).show();
}
});
container.addView(viewGroup);
return viewGroup;
}
Random rnd = new Random();
private int randomColor(){
return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view) {
//must be overridden else throws exception as not overridden.
Log.d("Tag", collection.getChildCount()+"");
collection.removeView((View) view);
}
#Override
public float getPageWidth(int position) {
return 0.8f;
}
}
MainActivity
public class MainActivity extends Activity {
private ViewPager viewPager;
LinearLayout linearLayout;
private int ID = 100;
private final int count = 8;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewPager);
linearLayout = (LinearLayout) findViewById(R.id.indicator_layout);
generateIndicators(count);
MyViewPagerAdapter adapter = new MyViewPagerAdapter(this, count);
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
int oldPosition = 0;
#Override
public void onPageSelected(int position) {
//this changes the old position's view state image
((TextView)linearLayout.getChildAt(oldPosition)).setText("");
oldPosition = position;
//this changes the current position's view state image
((TextView)linearLayout.getChildAt(position)).setText((position+1)+"");
}
//this method will be called repeatedly upto another item comes as front one(active one)
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
//this will be called as per scroll state
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
viewPager.setOffscreenPageLimit(4);
}
private void generateIndicators(int count) {
/// Converts 14 dip into its equivalent px
int padd = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics());
for(int i=0;i<count;i++){
TextView textView = new TextView(this);
textView.setId(ID+i);
final int currentItem = i;
textView.setBackgroundResource(R.drawable.white_cell);
textView.setPadding(padd,padd,padd,padd);
/// Converts 14 dip into its equivalent px
int size = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());
textView.setTextSize(size);
textView.setGravity(Gravity.CENTER);
/// Converts 14 dip into its equivalent px
int px = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(px, px);
linearLayout.addView(textView,params);
}
((TextView)linearLayout.getChildAt(0)).setText("1");
}
}
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" >
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</android.support.v4.view.ViewPager>
<LinearLayout
android:id="#+id/indicator_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="19dp" >
</LinearLayout>
</RelativeLayout>
item_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="match_parent"
android:id="#+id/root_view"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="click me" />
</LinearLayout>
Current screen
expected screen
For one app I implemented similar the following way, with standard ViewPager:
Make pages full-screen with the actual content in an inner layout. For example, make the full-screen layout a RelativeLayout with transparent background and the actual content another RelativeLayout centered in the parent. If I remember right, the reason for this was that with just the inner layout as a page, the ViewPager would not have taken all the screen width on some devices such as Galaxy Nexus.
Use ViewPager.setPageMargin() to set up a negative page margin i.e. how much of the next/previous page you want to show. Make sure it only overlaps the transparent region of the parent full-screen layout.
Call ViewPager.setOffscreenPageLimit() to adjust the off-screen page count to at least 2 from the default 1 to ensure smooth paging by really creating the pages off-screen. Otherwise you will see next/previous pages being drawn while already partially showing on screen.
For anyone upset that the OP didn't update his question with the solution here is a link that explains, with minimal effort, how to pull this off in XML: http://blog.neteril.org/blog/2013/10/14/android-tip-viewpager-with-protruding-children/
Basically when you declare your viewpager in XML, give it the same left and right padding and set android:clipToPadding="false". (The clipToPadding is missing in his xml sample and necessary to achieve this effect)
Finally, I have added my solution for this question in GitHub. I have done some pretty tricks to get the workaround solution. You can get the project from the below link(Actually I have planned to create a blog with the explanation , but I dint have that much time to do).
Here is the link(https://github.com/noundla/Sunny_Projects/tree/master/CenterLockViewPager)
You have to copy the files from com.noundla.centerviewpagersample.comps package to your project. And you can see the usage of that Viewpager in MainActivity class.
Please let me know if anyone has problems with this.
I found solution in this post, below the code i used:
// Offset between sibling pages in dp
int pageOffset = 20;
// Visible part of sibling pages at the edges in dp
int sidePageVisibleWidth = 10;
// Horizontal padding will be
int horPadding = pageOffset + sidePageVisibleWidth;
// Apply parameters
viewPager.setClipToPadding(false);
viewPager.setPageMargin(UIUtil.dpToPx(pageOffset, getContext()));
viewPager.setPadding(UIUtil.dpToPx(horPadding, getContext()), 0, UIUtil.dpToPx(horPadding, getContext()), 0);
dpToPx code:
public static int dpToPx(int dp, Context context) {
float density = context.getResources().getDisplayMetrics().density;
return Math.round((float) dp * density);
}
This is all you need
You can use padding for viewPager and set clipToPadding false
Java
viewPager.setClipToPadding(false);
viewPager.setPadding(50, 0, 50, 0);
Kotlin
viewPager.clipToPadding = false
viewPager.setPadding(50, 0, 50, 0)
I had to center current page in view pager with different page widths, so solution with paddings was not suitable. Also user scrolling was disabled (it was tab bar view pager, scrolled by another view pager). Here is a very simple solution to do that - just override ViewPager.ScrollTo method just like this (C# code, Xamarin):
public override void ScrollTo(int x, int y)
{
x -= (int) (MeasuredWidth * (1 - Adapter.GetPageWidth(CurrentItem)) / 2);
base.ScrollTo(x, y);
}
And if you calculate page width for each fragment don't forget to cache them in array.
Extend HorizontalScrollView class as the parent for the scrolling view. In the onMeasure() method you can specify the width and height of each child. Little cumbersome way but the effect will be good and you can have a good hold on your child view.
As showing on the picture. I want to display the star image above layout .
I am new to this type of coding .
my query is
1)will It possible to display star(image) on my layout side?
2)If on every click on my event I want to display star like and display like second image will it possible?
Means on same screen I have to save the star with their respect position .
thanks in Advanced?
Something like this :
public class MyActivity extends Activity implements View.OnTouchListener {
private RelativeLayout _mainLayout;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_mainLayout = (RelativeLayout)findViewById(R.id.canvas);
_mainLayout.setOnTouchListener(this);
}
#Override
public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
ImageView image = new ImageView(this);
image.setImageBitmap(bitmap);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(bitmap.getWidth(), bitmap.getHeight());
layoutParams.leftMargin = X - bitmap.getWidth()/2;
layoutParams.topMargin = Y - bitmap.getHeight()/2;
layoutParams.bottomMargin = -250;
layoutParams.rightMargin = -250;
image.setLayoutParams(layoutParams);
_mainLayout.addView(image);
break;
}
return false;
}
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:id="#+id/canvas"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/bg0large"
>
</RelativeLayout>
To do layout over layout, you should to use RelativeLayout.
If you want to display one layout over another layout you should use FrameLayout
http://developer.android.com/resources/articles/layout-tricks-merge.html