I have the following transition which I need to make when user scrolls the recyclerview down as shown in the image attached. The "Title A" and "Description" are inside a RelativeLayout and will collapse and their properties changed:
"Title A" from layout_centerHorizontal=true to layout_centerVertical=true
"Description" from layout_centerHorizontal=true to layout_centerVertical=true, textsize from 30sp to 16sp
Minimize the relativelayout, height from 70dp to wrap_content
When user scrolls up and hit the top, the changes will revert to original expanded form. (This is similar to the concept of collapsingtoolbar)
I've successfully implemented such that when i click on a button, the layout and views will change correctly using view.requestlayout(). But I'm not sure how to link the transitions to deltaY of onscrolled function.
Here is what I've tried:
changeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animateChanges();
}
});
private void animateChanges() {
ViewGroup.LayoutParams layout = relativeLayout.getLayoutParams();
RelativeLayout.LayoutParams header = (RelativeLayout.LayoutParams) titleA.getLayoutParams();
RelativeLayout.LayoutParams value = (RelativeLayout.LayoutParams) description.getLayoutParams();
// if current is not expanded, we change to expand view
if (!isExpanded) {
relativeLayout.setGravity(Gravity.CENTER);
layout.height = (int) getResources().getDimension(R.dimen.height_60);
header.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
header.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
header.addRule(RelativeLayout.CENTER_VERTICAL, 0);
value.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
value.addRule(RelativeLayout.BELOW, R.id.title_a);
value.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
value.addRule(RelativeLayout.CENTER_VERTICAL, 0);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
value.addRule(RelativeLayout.ALIGN_PARENT_END, 0);
header.addRule(RelativeLayout.ALIGN_PARENT_START, 0);
}
relativeLayout.setLayoutParams(layout);
titleA.setLayoutParams(header);
description.setLayoutParams(value);
description.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.font_30));
titleA.requestLayout();
description.requestLayout();
relativeLayout.requestLayout();
} else {
relativeLayout.setGravity(Gravity.CENTER_VERTICAL);
layout.height = ViewGroup.LayoutParams.WRAP_CONTENT;
header.addRule(RelativeLayout.CENTER_HORIZONTAL, 0);
header.addRule(RelativeLayout.BELOW, 0);
header.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
header.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
value.addRule(RelativeLayout.CENTER_HORIZONTAL, 0);
value.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
value.addRule(RelativeLayout.BELOW, 0);
value.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
value.addRule(RelativeLayout.ALIGN_PARENT_END, RelativeLayout.TRUE);
header.addRule(RelativeLayout.ALIGN_PARENT_START, RelativeLayout.TRUE);
}
titleA.setLayoutParams(header);
description.setLayoutParams(value);
relativeLayout.setLayoutParams(layout);
description.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.font_16));
relativeLayout.requestLayout();
titleA.requestLayout();
description.requestLayout();
}
isExpanded = !isExpanded;
}
Thanks in advance!
Related
I am using RecyclerView in which I have a RelativeLayout. In that RelativeLayout, I have a 2 TextView. If the first TextView has some value which decides if the second TextView should be aligned to right or left.
I have set the LayoutParams in RecyclerView Adapter using the below code:
if (listItem.getmLikeCount() > 0) {
RelativeLayout.LayoutParams feedCommentParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
feedCommentParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
listItemHolder.mCommentCount.setLayoutParams(feedCommentParams);
} else {
listItemHolder.mLikeCount.setVisibility(View.GONE);
RelativeLayout.LayoutParams feedCommentParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
feedCommentParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
listItemHolder.mCommentCount.setLayoutParams(feedCommentParams);
}
But the items are getting recycled i.e. if any of the RecyclerView items is not having any count then all other items are also aligned to the left.
I want to show the comment count to Right if like count > 0 else show comment count to left.
The problem can be easily solved with two TextView aligned separately. So that based on comments count you could set their visibility to GONE or VISIBLE.
Anyway, in your case you might consider calling the requestLayout inside the if and else statement like this.
if (listItem.getmLikeCount() > 0) {
RelativeLayout.LayoutParams feedCommentParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
feedCommentParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
listItemHolder.mCommentCount.setLayoutParams(feedCommentParams);
// Call requestLayout here
} else {
listItemHolder.mLikeCount.setVisibility(View.GONE);
RelativeLayout.LayoutParams feedCommentParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
feedCommentParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
listItemHolder.mCommentCount.setLayoutParams(feedCommentParams);
// Call requestLayout here for the else part.
}
I use this code for animate view in android its work perfect
problem when I set margin to zero or margin less the current margin its doesn't animate
the code
int margin = 100;
ValueAnimator varl = ValueAnimator.ofInt(margin);
varl.setDuration(200);
varl.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) myView.getLayoutParams();
lp.setMargins((Integer) animation.getAnimatedValue(), 0, 0, 0);
myView.setLayoutParams(lp);
}
});
varl.start();
Now when I set margin to 100 it animates, but when I want to set it to zero its set margin without animation
int margin = 0;
ValueAnimator varl = ValueAnimator.ofInt(margin);
varl.setDuration(200);
varl.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) myView.getLayoutParams();
lp.setMargins((Integer) animation.getAnimatedValue(), 0, 0, 0);
myView.setLayoutParams(lp);
}
});
varl.start();
The problem is that you didn't use the ValueAnimator.ofInt(int... values); correctly: you should explicitly tell the animator from which to which value it should animate. So, for example, you should animate from the current value to the wanted value. If your previous value, was, for example, 50, then the statement should be like this:
ValueAnimator varl = ValueAnimator.ofInt(50, margin);
You can use my library for that:
ViewPropertyObjectAnimator.animate(myView).leftMargin(100).setDuration(200).start();
I have a LinearLayout, i create(programatically) and adds buttons to it
public void initButtons(){
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
new android.app.ActionBar.LayoutParams(dpiToPixels(context, 100), dpiToPixels(context,100)));
params.setMargins(dpiToPixels(context,20), 0, 0, 0);
button.setLayoutParams(params);
}
layout.addView(button, index);
When user touch(onTouchListener) any button i want to scale it:
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) button
.getLayoutParams();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
lp.width = (int) (93 * Resources.getSystem()
.getDisplayMetrics().density);
lp.height = (int) (93 * Resources.getSystem()
.getDisplayMetrics().density);
button.setLayoutParams(lp);
}
else if (event.getAction() == MotionEvent.ACTION_UP) {
lp.width = (int) (100 * Resources.getSystem()
.getDisplayMetrics().density);
lp.height = (int) (100 * Resources.getSystem()
.getDisplayMetrics().density);
button.setLayoutParams(lp);
}
return false;
}
});
The problem is that when i press one button down it affects every other buttons on the LinearLayout( looks scaled and moving a little left). Anyone has any idea how to solve this?
This is bound to happen in a LinearLayout.
Try using FrameLayout. In a frameLayout, changing one button size won't affect others.
You can also use a RelativeLayout, but you shouldn't position your buttons 'relative' to others in it.
<ScrollView
android:id="#+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#id/btnAddRow"
android:layout_below="#id/llInventoryViewHeader"
android:isScrollContainer="true"
android:scrollbars="vertical" >
<LinearLayout
android:id="#+id/llDynamicView"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
Code which set rows in linear layout :-
/**
* Set Edit text
*/
private void setUsedList() {
for (final InventoryResource inventoryResource : mCurrentUsedResourceList) {
final LinearLayout LL = new LinearLayout(InventoryActivity.this);
LL.setOrientation(LinearLayout.HORIZONTAL);
final LayoutParams LLParams = new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
LL.setWeightSum(10f);
LL.setLayoutParams(LLParams);
// ResourceName Params
final LinearLayout.LayoutParams resourceViewParams = new LinearLayout.LayoutParams(
0, LinearLayout.LayoutParams.WRAP_CONTENT);
resourceViewParams.weight = 6f;
resourceViewParams.setMargins(5, 5, 5, 5);
// Resource Edittext
final EditText edtTextResourceName = new EditText(
InventoryActivity.this);
edtTextResourceName.setGravity(Gravity.CENTER);
edtTextResourceName.setLayoutParams(resourceViewParams);
edtTextResourceName.setInputType(InputType.TYPE_CLASS_TEXT);
edtTextResourceName.setTextColor(Color.BLACK);
edtTextResourceName.setTextSize(16f);
edtTextResourceName.setBackground(getResources().getDrawable(
R.drawable.box_edt_values));
// Amount Params
final LinearLayout.LayoutParams amtViewParams = new LinearLayout.LayoutParams(
0, LinearLayout.LayoutParams.WRAP_CONTENT);
amtViewParams.weight = 2f;
amtViewParams.setMargins(5, 5, 5, 5);
final EditText edtTextConstructorAmt = new EditText(
InventoryActivity.this);
edtTextConstructorAmt.setGravity(Gravity.CENTER);
edtTextConstructorAmt.setInputType(InputType.TYPE_CLASS_PHONE);
edtTextConstructorAmt.setLayoutParams(amtViewParams);
edtTextConstructorAmt.setTextColor(Color.BLACK);
edtTextConstructorAmt.setTextSize(16f);
edtTextConstructorAmt.setBackground(getResources().getDrawable(
R.drawable.box_edt_values));
final EditText edtTextInspectorAmt = new EditText(
InventoryActivity.this);
edtTextInspectorAmt.setInputType(InputType.TYPE_CLASS_PHONE);
edtTextInspectorAmt.setGravity(Gravity.CENTER);
edtTextInspectorAmt.setLayoutParams(amtViewParams);
edtTextInspectorAmt.setTextColor(Color.BLACK);
edtTextInspectorAmt.setTextSize(16f);
edtTextInspectorAmt.setBackground(getResources().getDrawable(
R.drawable.box_edt_values));
final InventoryPojo pojo = new InventoryPojo();
pojo.id = inventoryResource.getOrderNum();
mOrderNumber += 1;
pojo.edtResourceName = edtTextResourceName;
pojo.edtConstructoreAmt = edtTextConstructorAmt;
pojo.edtInspectoreAmt = edtTextInspectorAmt;
mUsedList.add(pojo);
if (mPreference.getString(Preferences.LAN_CULTURE,
Constants.CULTURE_HEBREW).equalsIgnoreCase(
Constants.CULTURE_ENGLISH)) {
LL.addView(edtTextResourceName);
LL.addView(edtTextConstructorAmt);
LL.addView(edtTextInspectorAmt);
mLLDetails.addView(LL);
mLLDetails.invalidate();
} else {
LL.addView(edtTextInspectorAmt);
LL.addView(edtTextConstructorAmt);
LL.addView(edtTextResourceName);
mLLDetails.addView(LL);
mLLDetails.invalidate();
}
}
}
Code :-
parent = (RelativeLayout)findViewById(R.id.rlParent);
parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
public void onGlobalLayout(){
int heightDiff = parent.getRootView().getHeight()- parent.getHeight();
// IF height diff is more then 150, consider keyboard as visible.
if(heightDiff > 150){
// Its keyboard mostly
parent.setPadding(0, 0, 0, heightDiff);
}
else if(heightDiff < 150){
// Keyboard goes away, readjust
parent.setPadding(0, 0, 0, 0);
}
}
});
I am having scroll view inside which dynamically rows are being added. The problem i am facing is that if my view is having 10 rows then when i start typing it won't scroll upto end. For e.g. in case of 10 rows I am able to scroll up to 7 row and then other 3 rows are not visible and have to close the keyboard by pressing back and then i can add the value to rest 3 row.
I have added inputMode to adjustPan in my manifest for the activity and also added android:isScrollContainer="true" but still its not working.
Anyone having any idea how to resolve it.
Okay, try this it might save your cause,
first in your main XML which holds this Scroll view give identefier to its root i.e its parent
Second, android does provide you an API which tell you about dimensions of its view which are assigned to them right before they are drawn, this you can read through ViewTreeObservers
use this code to check when keyboard is inflated, when its inflated, you can assign the height differece as padding bottom to your parent view, and when keyboard goes away just reset the padding set. this will make sure you can scroll all view which are hidden beneath inflated keyboad.
parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
public void onGlobalLayout(){
int heightDiff = parent.getRootView().getHeight()- parent.getHeight();
// IF height diff is more then 150, consider keyboard as visible.
if(heightDiff > 150){
// Its keyboard mostly
parent.setPadding(0, 0, 0, heightDiff);
}
else if(heightDiff < 150){
// Keyboard goes away, readjust
parent.setPadding(0, 0, 0, 0);
}
}
});
4 make sure you have this parameter defined in you activity in manifiest file
android:windowSoftInputMode="adjustResize"
You might want to play around with the windowSoftInputMode. And here's an interesting discussion that helped me solve my similar problem.
Hope this helps you!
Your scrollview seems to be fine.
For doing scroll you just have to add single line inside your activity of manifiest file.
android:windowSoftInputMode="adjustResize"
i create a dynamic view ( linearlayout ) with
table.addView(view, layoutParams);
I want when I click on view1 the background color turns white,
when I click on view2 the background color of view1 turns black and the background color of view2 turns white, and if I click on view3 the background color of view2 turns black and the background color of view3 turns white ...
private void addToRow(int rowID, TimeCard timecard, int offset) {
LayoutParams tlparams = new LinearLayout.LayoutParams(TIMECARD_WIDTH,
LinearLayout.LayoutParams.WRAP_CONTENT);
tlparams.setMargins((int) offset, 150-50*rowID, 0, 0);
System.out.println("rowID= "+50*rowID);
View v = timecard.getView(context);
v.setOnClickListener(this);
rows.get(rowID).addView(v, tlparams);
}
private void addRowsToTable() {
LayoutParams layoutParams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
for (LinearLayout row : rows) {
layoutParams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//table is an absolutlayout and i add many row in this layout
table.addView(row, layoutParams);
}
tableNavbar.addView(llnavBar, layoutParams);
}
#Override
public void onClick(View v) {
v.setBackgroundResource(R.drawable.cadre_blanc);
TextView t1=(TextView)v.findViewById(R.id.tc_title);
t1.setTextColor(Color.rgb(0, 139, 221));
}
how can i do this please??