Use SnapHelper to Scroll to a Child view in a recyclerview item - android

In my recyclerview onCreateViewholder method I create a dynamic which would have unspecified number of text views inside a linear layout
if (sessionManager.getBookScrolOrientation() == AppConstents.HORIZONTAL) {
LinearLayout linearLayout = new LinearLayout(context);
ViewGroup.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT , ViewGroup.LayoutParams.MATCH_PARENT);
linearLayout.setLayoutParams(layoutParams);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
Spannable spannable = getVerseSpanableHorizontal(pidreference.get(position) , cidreference.get(position));
Pagination pagination = new Pagination(spannable,
pageWidth,
pageHight,
textPaint,
lineSpacingMultiplier,
lineSpacingExtra,
isTextPaddingIncluded);
List<CharSequence> list = pagination.getPages();
for (CharSequence charSequence : list){
TextView tv = new TextView(linearLayout.getContext());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(Tools.getScreenWidth() , ViewGroup.LayoutParams.MATCH_PARENT);
tv.setLayoutParams(params);
tv.setText(charSequence);
linearLayout.addView(tv);
}
MainViewHolder viewHolder = new MainViewHolder(linearLayout);
return viewHolder;
}
When i use SnapHelper with this recyclerview it scrolls to the center of linear layout not the next textview. How can i make it scroll to the next textview inside the linearlayout?

If I understand correctly, the problem is that SnapHelper snaps the center of the current view to the center of the recycler. As the docs say:
The implementation will snap the center of the target child view to the center of the attached RecyclerView.
If you want the the current view to snap to the start of the recycler use a libraray such as this one. Import it with gradle and activate it like this:
GravitySnapHelper(Gravity.START).attachToRecyclerView(recyclerview);

Related

Cannot center text when programmatically creating view from adaptor

I am using an adaptor to generate a view for each of several items. The view needs to show an image with centered text below it. I create a linear layout and add an image view and text view.
To show the problem I have changed the background colors to green for the linear layout and red for the text view...
Obviously the text is showing left aligned instead of centered. Here is the simple code in the adaptor GetView method...
public override View GetView(int position, View convertView, ViewGroup parent)
{
ImageView imageView = new ImageView(_context);
LinearLayout.LayoutParams imageViewParam = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent, LinearLayout.LayoutParams.WrapContent);
imageView.LayoutParameters = imageViewParam;
imageView.Id = 1000 + position;
imageView.SetImageResource(Resource.Drawable.Code);
TextView textView = new TextView(_context);
LinearLayout.LayoutParams textViewParam = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent, LinearLayout.LayoutParams.WrapContent);
textView.LayoutParameters = textViewParam;
textView.Text = OPTIONS_TEXT[position];
textView.SetBackgroundColor(Color.Red);
textView.SetForegroundGravity(GravityFlags.CenterHorizontal);
LinearLayout linear = new LinearLayout(_context);
linear.LayoutParameters = new GridView.LayoutParams(200, 172);
linear.SetBackgroundColor(Color.Green);
linear.Orientation = Orientation.Vertical;
linear.AddView(imageView);
linear.AddView(textView);
return linear;
}
As far as I can work out, you cannot set the layout_gravity setting when generating the view programmatically and so I tried setting the foreground gravity but has no effect at all.
I have tried everything I can think of but nothing gets that text centered!
Set gravity center to LinearLayout.LayoutParams of TextView i.e.
textViewParam.gravity = Gravity.CENTER;

How to set position of view while using addView

I'm adding multiple Views by code into Layout. I need each new View to be above previous one(top of the parent layout).
EDIT: To be more accurate I'll describe what the app module should does. User start with clean screen and one button at the bottom of the screen. The button adds a View at the top of the screen. Next clicks should add next views above previous ones to make the newest View be on the top of a container. The app saves state and on restart user see views in the same order.
Call the following method from Button's onClick Event.
private final int LAYOUT_TOP_INDEX = 0;
private void addViewOnTop(View view){
if(layout != null && view !=null)
layout.addView(view, LAYOUT_TOP_INDEX);
}
where 'layout' is your Layout (e.g., LinearLayout) to which the View is to be added.
Would really need more information from you to give a more accurate answer, but if you're saying what i think you are then you can just add these views to a LinearLayout with orientation set to vertical.
And assuming you're iterating through a list to dynamically add views, instead of incrementing from 0, increment down from the size of the list.
for(int i = size; i >= 0; i--){
linearLayout.add(new TextView(Context));
}
View positions inside ViewGroups are defined by the LayoutParams
How does this happen? Views pass their LayoutParams to their parent ViewGroups
//100% programatic approach with simple LayoutParams
LinearLayout myLinearLayout = new LinearLayout(this);
//if the **parent** of the new linear layout is a FrameLayout
FrameLayout.LayoutParams layoutParams =
new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
//or if you have the XML file you don't have to worry about this
//myLinearLayout = (LinearLayout)findViewById(R.id.my_simple_linear_layout);
//you could have a LinkedList<TextView>
LinkedList<TextView> textViewList = new LinkedList<>();
//assuming the order is the correct order to be displayed
Iterator<TextView> descendingIterator = textViewList.descendingIterator();
while(descendingIterator.hasNext())
{
//just add each TextView programatically to the ViewGroup
TextView tView = descendingIterator.next();
myLinearLayout.addView(tView);
}
Just like we defined LayoutParams for the LinearLayout we could also define LayoutParams for the TextView
IMPORTANT: when setting LayoutParams you need to be sure they fit the VIEWGROUP, that is the parent of the View being added
private TextView textViewFactory(String myText) {
TextView tView = new TextView(getBaseContext());
//controling the position relatively to the PARENT
//because you are adding the textview to a LINEAR LAYOUT
LinearLayout.LayoutParams paramsExample =
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
tView.setLayoutParams(paramsExample);
//configuring the insides of the textview
//you can also do all kinds of stuff programatically
tView.setGravity(Gravity.CENTER_HORIZONTAL);
tView.setPadding(10, 10, 10, 10);
tView.setTypeface(Typeface.DEFAULT_BOLD);// (null, Typeface.BOLD_ITALIC);
tView.setTypeface(Typeface.SANS_SERIF);
tView.setTypeface(null, Typeface.ITALIC);
tView.setTypeface(Typeface.defaultFromStyle(R.style.AppTheme));
tView.setId(R.id.aux_info);
tView.setText(myText);
//.........all kinds of stuff really
return tView;
}
If you mean adding a view programmatically so that the new one is added above the previous one, instead of below it, then I suggest this:
Maintain an ArrayList with the items you want to turn into views
Put them into a ListView
When you want to add a new view that must appear at the top of the list, insert it as the first element of your ArrayList and recreate the ListView from it.

Adding view below another recently animated view

I have edit view that I animated from the middle of the screen to the top using object animator:
animators.add(ObjectAnimator.ofFloat(ev, "y", 0));
On animationEnd I try to add another view below it:
EditText ev2= new EditText(getActivity());
ev2.setText("Test");
RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params2.addRule(RelativeLayout.BELOW, ev.getId()); // first view id (ev)
params2.leftMargin = 107;
groupView.addView(ev2, params2);
This will be added below to the original position of the first edit view. How can I add other view exactly below the view after animation.
Just use LinearLayout with vertical orientation.

How to dynamically wrap root layout in a ScrollView

I want to add a scroll view to all the layouts that I have. But dynamically. Because the app will run in different screen sizes, and when I will get a screen size smaller than a specific size, then I want to show the layout in a scroll view.
So I made this method, it will be called on the check that the screen is small. I will pass my activity and I want to change the root layout to scroll view or just add a ScrollView as the root layout. So if the root layout is a LinearLayout, then I want to put that layout in the ScrollView. And I have not named all the layouts, meaning that I didn't give an ID to the layout, so I cannot use findViewById.
public static void SetActivityRoot(Activity c) {
View v = c.getWindow().getDecorView();
// View v = v.getRootView();
ScrollView sv = new ScrollView(c);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
sv.setLayoutParams(lp);
((ViewGroup)v.getParent()).removeView(v);
sv.addView((View) v);
((ViewGroup)v.getParent()).addView(sv);
}
It's giving me an error saying that "you cannot remove view from null" etc. Or that "you cannot add view to layout as it already has parent view". How can I make this work?
Finally solved my problem.
public static void SetActivityRoot(Activity c) {
View v = ((ViewGroup)c.findViewById(android.R.id.content)).getChildAt(0);
ScrollView sv = new ScrollView(c);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
sv.setLayoutParams(lp);
((ViewGroup) v.getParent()).removeAllViews();
sv.addView((View) v);
c.addContentView(sv, lp);
}

Bottom part not display in linear layout using scrollview

I have linear layout but bottom part not display if scrolling data is more then screen size.
Streaching Bottom Part when Using Scrollview inside the linearlayout, when scrolling data more then height of the device height.
If i have less data then vertical screen size then all button of bottom appears correctly.
public class TestGUI extends LinearLayout {
sv = new ScrollView(context);
hsv = new HorizontalScrollView(context);
this.addView(topLinearHorizonal);
hsv.addView(tableLayout);
sv.addView(hsv);
this.addView(sv);
this.addView(fullbottomLinearHorizonal);
}
Edited:
LinearLayout fullbottomLinearHorizonal= new LinearLayout(context);
fullbottomLinearHorizonal.setOrientation(VERTICAL);
fullbottomLinearHorizonal.addView(clearLinearHorizonal);
fullbottomLinearHorizonal.addView(bottomLinearHorizonal);
If you want to show fullbottomLinearHorizonal always at the bottom(visible) you can try below while adding views to TestGUI:
LinearLayout.LayoutParams svParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1);
this.addView(sv, svParams);
LinearLayout.LayoutParams fullbottomParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, WRAP_CONTENT);
this.addView(fullbottomLinearHorizonal, fullbottomParams);
Edit: Also default orientation for LinearLayout is horizontal. See link.
You should better set it vertical at TestGUI:
this.setOrientation(VERTICAL);
If you want fullbottomLinearHorizonal at the end of the scroll content then you must add it inside of the scrollView.

Categories

Resources