I have a PreferenceFragment whose contents are defined in XML. These contents include a child PreferenceScreen. When I click on the PreferenceScreen, the new screen is rendered successfully, but it has no animation (it just shows up on screen, even before the Material ripple is finished on Lollipop devices).
Even worse, if I had any complex layout going on (for example, the PreferenceFragment was in a tab on one side of the screen) that layout is blown away and replaced with a full-screen fragment.
I suspect that if I find the callback or event that occurs when a PreferenceScreen is clicked, I can solve both problems, but I don't really know where to start.
I did this for a slide in right-to-left animation of the PreferenceFragment...
I extended the PreferenceFragment and overridden the onCreateView() like this:
#Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
AnimRelativeLayout animRelativeLayout = new AnimRelativeLayout(getActivity());
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
animRelativeLayout.setLayoutParams(layoutParams);
animRelativeLayout.addView(view);
return animRelativeLayout;
}
where AnimRelativeLayout.java is
public class AnimRelativeLayout extends RelativeLayout {
private IMovementListener mMovementListener;
public AnimRelativeLayout(Context context) {
super(context);
this.initMembers();
}
public AnimRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.initMembers();
}
public AnimRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.initMembers();
}
private void initMembers() {
this.mMovementListener = new SimpleMovementListener();
}
public float getXFraction() {
final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
return (width == 0) ? 0 : getX() / (float) width;
}
public void setXFraction(float xFraction) {
final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
this.mMovementListener.onSetXFraction(xFraction);
setX((width > 0) ? (xFraction * width) : 0);
}
public float getYFraction() {
final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int height = size.y;
return (height == 0) ? 0 : getY() / (float) height;
}
public void setYFraction(float yFraction) {
final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int height = size.y;
this.mMovementListener.onSetYFraction(yFraction);
setY((height > 0) ? (yFraction * height) : 0);
}
public interface IMovementListener {
public void onSetXFraction(float pXFraction);
public void onSetYFraction(float pYFraction);
}
private class SimpleMovementListener implements IMovementListener {
#Override
public void onSetXFraction(float pXFraction) {
}
#Override
public void onSetYFraction(float pYFraction) {
}
}
and then did this:
pFragmentManager.beginTransaction()
.setCustomAnimations(
R.animator.slide_in_right_to_left, R.animator.slide_out_right_to_left,
R.animator.slide_in_left_to_right, R.animator.slide_out_left_to_right
)
.replace(R.id.fragment_container, fragment)
.commit();
and an example for R.animator.slide_in_right_to_left is:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:propertyName="xFraction"
android:valueFrom="1.0"
android:valueTo="0"
android:valueType="floatType"/>
</set>
Related
i have a customview that extend from FrameLayout:
public class FanView extends FrameLayout {
private static final String TAG = FanView.class.getSimpleName();
private List<FanItem> fanItems = new ArrayList<>();
private float openRatio = 0f;
public FanView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setStaticTransformationsEnabled(true);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Log.d(TAG, "onLayout(" + changed + ", " + left + ", " + top + ", " + right + ", " + bottom + ")");
super.onLayout(changed, left, top, right, bottom);
Log.d(TAG, "End onLayout");
}
#Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
final float index = getChildCount() - indexOfChild(child) - 1;
final float height = child.getHeight();
Matrix matrix = t.getMatrix();
matrix.setTranslate((float) (-index * 1.1 * (height/2) * openRatio), (float) (index * height * openRatio * 1.2));
return true;
}
public void setOpenRatio(float r) {
this.openRatio = r;
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
view.invalidate();
}
invalidate();
}
public void setFanItems(List<FanItem> fanItems) {
this.fanItems = fanItems;
removeAllViewsInLayout();
for (int i = 0; i < fanItems.size(); i++) {
int fanItemIndex = fanItems.size() - i - 1;
FanItem fanItem = fanItems.get(fanItemIndex);
View fanView = inflate(getContext(),
fanItemIndex == 0 ? R.layout.fan_item_header : R.layout.fan_item, null);
TextView textView = (TextView) fanView.findViewById(R.id.fan_view_item_title);
textView.setText(fanItem.getTitle());
addViewInLayout(fanView, i,
new LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
}
invalidate();
}
}
in xml layout i use this custom view with width and height wrap_content.
when i add view to that custom view not show this views,
because custom layout not change it's size.
how to say to custom view that change it's size
Your current code probably needs another constructor
public FanView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
Please provide valid size to inflate the items at first. Give at least one element to acquire size after layout inflation. You can change the size of items using layout params.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="schemas.android.com/apk/res/android"
android:background="#drawable/fan_item_background"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textDirection="rtl">
<TextView
android:id="#+id/fan_view_item_title"
android:layout_height="200dp"
android:layout_width="200dp"
android:text="ersfsdf"
android:textAlignment="textStart"
android:textColor="#ffffff"/>
</FrameLayout>
To change the size dynamically try something like this .
// Gets linearlayout
FrameLayout layout = findViewById(R.id.framelaut);// or any layout
// Gets the layout params that will allow you to resize the layout
LayoutParams params = layout.getLayoutParams();
// Changes the height and width to the specified *pixels*
params.height = 100;
params.width = 100;
layout.setLayoutParams(params);
How i can make StaggeredGridLayoutManager auto_fit with all screens size , set number of columns automatically
recyclerViewadapter = new RecyclerViewAdapter(GetDataAdapter1, this);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(recyclerViewadapter);
If your items are at the same width, you can do this:
mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
mRecyclerView.getViewTreeObserver().removeOnGLobalLayoutListener(this);
int viewWidth = mRecyclerView.getMeasuredWidth();
float cardViewWidth = getActivity().getResources().getDimension(R.dimen.cardview_layout_width);
int newSpanCount = (int) Math.floor(viewWidth / cardViewWidth);
mLayoutManager.setSpanCount(newSpanCount);
mLayoutManager.requestLayout();
}
});
Create help class for getting sizes.
public class GetSize {
public static int getColumnCount(Context context, int dp) {
if ((double) (getScreenWidth(context)/getPointOfDp(context, dp)) <= 1) return 1;
else return getScreenWidth(context)/getPointOfDp(context, dp);
}
public static int getScreenWidth(Context context){
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point point = new Point();
display.getSize(point);
return point.x; //Screen width
}
private static int getPointOfDp(Context context, int dp) { //Convert from dp to screen dots
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}
}
For get a column count need set some minimal width of your item.
int columnCount = GetSize.getColumnCount(context, 288);
layoutManager = new StaggeredGridLayoutManager(columnCount, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
Try this
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(getSpan(), StaggeredGridLayoutManager.VERTICAL);
public int getSpan() {
int orientation = getScreenOrientation(getActivity());
if (isTV(getActivity())) return 4;
if (isTablet(getActivity()))
return orientation == Configuration.ORIENTATION_PORTRAIT ? 2 : 3;
return orientation == Configuration.ORIENTATION_PORTRAIT ? 2 : 3;
}
public static boolean isTV(Context context) {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2 && ((UiModeManager) context
.getSystemService(Context.UI_MODE_SERVICE))
.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION;
}
public static int getScreenOrientation(Context context) {
return context.getResources().getDisplayMetrics().widthPixels <
context.getResources().getDisplayMetrics().heightPixels ?
Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
}
public static boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
I have a custom HorizontalScrollView.But inside the class,the method smoothScrollTo doesn't work.The codes below is mine.
public class MyHorizontalScrollView extends HorizontalScrollView {
private int flagPosition;
private int scrollX;
private int windowWidth;
public MyHorizontalScrollView(Context context) {
super(context);
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
windowWidth = outMetrics.widthPixels;
flagPosition = windowWidth / 2;
}
public MyHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
windowWidth = outMetrics.widthPixels;
flagPosition = windowWidth / 2;
}
public MyHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
windowWidth = outMetrics.widthPixels;
flagPosition = windowWidth / 2;
}
#Override
public void setSmoothScrollingEnabled(boolean smoothScrollingEnabled) {
super.setSmoothScrollingEnabled(true);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
scrollX = getScrollX();
break;
case MotionEvent.ACTION_UP:
scroll();
break;
}
return super.onTouchEvent(ev);
}
private void scroll() {
if (scrollX <= flagPosition/2) {
smoothScrollTo(0, 0);
} else{
smoothScrollTo(flagPosition, 0);
}
}
#Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
scrollX = getScrollX();
Log.v("my", "myscroll======+++++++onscrollchange" + scrollX);
}
}
I want a result that,I scroll the HorizontalScrollView,when I scroll to a range,then uplift my finger,the HorizontalScrollView will scroll to a specific position automaticly.
This is my code.Inside the method scroll(),I toggle smoothScrollTo.It doesn't work.But the method scrollTo worked.I don't know why.
I put the codes inside the class:
private Runnable run = new Runnable() {
#Override
public void run() {
if (scrollX <= flagPosition / 2) {
MyHorizontalScrollView.this.smoothScrollTo(0, 0);
} else {
MyHorizontalScrollView.this.smoothScrollTo(flagPosition, 0);
}
}
};
#Override
public boolean post(Runnable action) {
return super.post(action);
}
Then replace the method smoothScrollTo with post().And I realize the effect.
I have a horizontal Recycler View and I want to enable snapping in it. I read some of the threads on SO and found this code to be working very well. I don't have much knowledge about the internal workings of Recycler View and Layout Managers so wanted to ask if the code can be modified to:
No matter what the velocity of fling, I want to move only one item forward or backward.
The snapping speed is slow. If I move the view more than half the width, the next item comes into center but very slowly. Can this be increased so that the snap is instant?
Any ideas on how to achieve the above behaviors would be highly helpful.
Finally figured it out with some help from other codes:
public class FlingRecyclerView extends RecyclerView {
int screenWidth;
public FlingRecyclerView(Context context) {
super(context);
WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
screenWidth = size.x;
}
public FlingRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
screenWidth = size.x;
}
public FlingRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
screenWidth = size.x;
}
#Override
public boolean fling(int velocityX, int velocityY) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();
//these four variables identify the views you see on screen.
int lastVisibleView = linearLayoutManager.findLastVisibleItemPosition();
int firstVisibleView = linearLayoutManager.findFirstVisibleItemPosition();
View firstView = linearLayoutManager.findViewByPosition(firstVisibleView);
View lastView = linearLayoutManager.findViewByPosition(lastVisibleView);
//these variables get the distance you need to scroll in order to center your views.
//my views have variable sizes, so I need to calculate side margins separately.
//note the subtle difference in how right and left margins are calculated, as well as
//the resulting scroll distances.
int leftMargin = (screenWidth - lastView.getWidth()) / 2;
int rightMargin = (screenWidth - firstView.getWidth()) / 2 + firstView.getWidth();
int leftEdge = lastView.getLeft();
int rightEdge = firstView.getRight();
int scrollDistanceLeft = leftEdge - leftMargin;
int scrollDistanceRight = rightMargin - rightEdge;
//if(user swipes to the left)
if (velocityX > 0) smoothScrollBy(scrollDistanceLeft, 0);
else smoothScrollBy(-scrollDistanceRight, 0);
return true;
}
}
Works awesome for my requirements. Hope it helps someone else too.
I using both Using Activity or without Activity, Not getting both height and width in Android.Please correct me, What i am doing wrong.
Here With Activity:
public class LandPort extends Activity{
public final static int height = 0;
public final static int width = 0;
Context context;
DisplayMetrics displaymetrics = new DisplayMetrics();
public LandPort(Context context) {
this.context = context;
}
public int getHeight() {
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
return height;
}
public int getWidth() {
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = displaymetrics.widthPixels;
return width;
}
}
In MainActivity:
LandPort lp= new LandPort(getApplicationContext());
int height = lp.getHeight();
int width =lp.getWidth();
Getting height and width both 0;
Another Without Activity:
public class GetHeigthWidth {
public final static int height = 0;
public final static int widht = 0;
Context context;
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
public GetHeigthWidth(Context context) {
this.context = context;
}
public int getHeight() {
#SuppressWarnings("deprecation")
int height = display.getHeight();
return height;
}
public int getWidth() {
#SuppressWarnings("deprecation")
int widht = display.getWidth();
return widht;
}
}
From MainActivty:
GetHeigthWidth ghw= new GetHeigthWidth(getApplicationContext());
int height = ghw.getHeight();
int width =ghw.getWidth();
Aslo get Height and Width 0.
So, How to get Actual Height and width in this>
call your getHeight(); getWidth() stuff in
int height;
int width;
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(globalListner);
OnGlobalLayoutListener globalListner = new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
height = view.getHeight();
widht = view.getWidth();
}
});
and dont forget to remove that global listner at the End :)
Try this
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
setContentView(R.layout.yourLayout);
}
you need to initialize your activity.
UPDATE
You need to do this:
import android.content.Context;
import android.view.Display;
import android.view.WindowManager;
public class GetHeigthWidth {
public final static int height = 0;
public final static int widht = 0;
Context context;
WindowManager wm;
Display display;
public GetHeigthWidth(Context context) {
this.context = context;
wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
display = wm.getDefaultDisplay();
}
public int getHeight() {
#SuppressWarnings("deprecation")
int height = display.getHeight();
return height;
}
public int getWidth() {
#SuppressWarnings("deprecation")
int widht = display.getWidth();
return widht;
}
}
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;