How to get child views of recyclerview for printing? - android

full view of all the items of recyclerview should be added to a single view.Is it possible in recyclerview. Right now I've done something like this,
for(int i=0; i<=adapter.getItemCount(); i++){
View view = layoutManager.findViewByPosition(i);
}
But it is returning null for every iteration of "i".please suggest answer for this.

Try this.
YourViewHolder holder = recyclerview.findViewHolderForAdapterPosition(position);
View view = holder.itemView;
//now you have the rootView for each row

Related

RecyclerView Showing Random Data

I am having a RecyclerView with a Custom Adapter which extends RecyclerView.Adapter
I am Creating LinearLayout with Textview at Runtime and inflating it in each row of RecyclerView
For Example, 1st Row of RecyclerView will have 2 or 3 Textview created at runtime, 2nd Row will have 2 or 3 Textviews created at runtime, 3rd Row will have some Textviews...and so on...
Its working almost Prefect if I check my Log... But when I scroll it down, it just places some textview in wrong places, means I get previous Textviews again when I scroll down in wrong places
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
//Movie movie = mItems.get(i);
hm2 = new HashMap<String, ArrayList<PD_Data>>();
sub_rows2 = new ArrayList<PD_Data>();
hm2=categories.get(i);
String key=hm2.keySet().toArray()[0].toString();
sub_rows2=hm2.get(key);
Log.i(LOG_TKT,key);
viewHolder.textview_category.setText(key);
LayoutInflater inflater;
View new_sub_row;
for(int x=0;x<sub_rows2.size();x++){
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
new_sub_row = inflater.inflate(R.layout.recyclerview_pd, null);
TextView heading2 = (TextView)new_sub_row.findViewById(R.id.heading2);
heading2.setText(sub_rows2.get(x).sub_heading);
Log.i(LOG_TKT,sub_rows2.get(x).sub_heading);
TextView detail2 = (TextView)new_sub_row.findViewById(R.id.detail2);
detail2.setText(sub_rows2.get(x).value);
Log.i(LOG_TKT, sub_rows2.get(x).value);
viewHolder.linearlayout_recyclerview_pd.addView(new_sub_row);
}
//viewHolder.imgThumbnail.setImageResource(movie.getThumbnail());
hm2 = new HashMap<String, ArrayList<PD_Data>>();
sub_rows2 = new ArrayList<PD_Data>();
}
What am I doing wrong ?
It is obvious from your question that you aren't familier with how to use RecyclerViews. You need to read up on the subject. Here is a good start.
Basically, onBindViewHolder() is only responsible for binding your data to your viewHolders which hold your item layouts provided by you through onCreateViewHolder(). The reason for that is that RecyclerView recycles your views so it doesn't have to create new views every time you scroll.
In your case, it appears that you would need to use some technique that will tell the RecyclerView to use different viewHolders for different items. See how you can do it here.
I have given answer for better practice of binding data with ViewHolder in another question. You can check it here RecyclerView causes issue when recycling I hope this will help you. This will solve you problem well.
EDIT
Have you solved your problem yet? If not , consider my advice. You know the problem right? suppose you create a ViewHOlder for item 0 and add some text in it. While scrolling suppose this ViewHolder recycled for item number 10, then according to your code it will add new text rows along with some text rows you added for item number 0. You can solve it like
LayoutInflater inflater;
View new_sub_row;
//check here if the linear layout already has previusely added child, if yes remove them
if(viewHolder.linearlayout_recyclerview_pd.getChildCount()>0){
viewHolder.linearlayout_recyclerview_pd.removeAllViews();
}
for(int x=0;x<sub_rows2.size();x++){
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
new_sub_row = inflater.inflate(R.layout.recyclerview_pd, null);
TextView heading2 = (TextView)new_sub_row.findViewById(R.id.heading2);
heading2.setText(sub_rows2.get(x).sub_heading);
Log.i(LOG_TKT,sub_rows2.get(x).sub_heading);
TextView detail2 = (TextView)new_sub_row.findViewById(R.id.detail2);
detail2.setText(sub_rows2.get(x).value);
Log.i(LOG_TKT, sub_rows2.get(x).value);
viewHolder.linearlayout_recyclerview_pd.addView(new_sub_row);
}

Not being able to add multiple child views to parent view

I am trying to add multiple relative layouts to a Linear layout. I am using the following lines of code.
LayoutInflater inflator = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout item = (LinearLayout)findViewById(R.id.reviews);
for(int i=0 ; i<2 ; i++){
View child = inflator.inflate(R.layout.review_item, null);
child.setId(i);
child.setTag(i);
item.addView(child);
}
But I can only see one child view. Can anyone tell me where I am going wrong.
Declare the LinearLayout item outside of the for loop.
The way you're doing it the variables value will be overwritten each time you run through the for loop. So your method should look like this:
public void somemethod(){
LayoutInflater inflator = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout item = (LinearLayout)findViewById(R.id.reviews);
for(int i=0 ; i<2 ; i++)
{
View child = inflator.inflate(R.layout.review_item, null);
child.setId(i);
child.setTag(i);
item.addView(child);
}
}
You need to take the first two lines outside of the for loop. You're inflating the LinearLayout twice, which overrides the first layout you inflate, rather than adding to it. By putting those two lines before the for loop starts, you'll add both child views to a single LinearLayout.

reuse the inflated view in android

The following piece of code is inflating the same view for 20 times. Since inflating is costly. I want to inflate it only one, and use the same view for 20 items, i just want to change the visible data in the UI.
LinearLayout ll = new LinearLayout(context);
for (int i = 0; i < 20; ++i) {
View itemView = inflater.inflate(getLayoutId(), parent, false);
itemView.setText(data.getName(i);
ll.add(itemView);
}
I want something like this.
LinearLayout ll = new LinearLayout(context);
View itemView = inflater.inflate(getLayoutId(), parent, false);
for (int i = 0; i < 20; ++i) {
itemView.setText(data.getName(i);
ll.add(itemView);
}
But am not able to use the itemView obj this way.
Can anyone tell me how to use the view many times once it inflated.
You cannot do that. If you think its costly then find another way to create your layout.
But consider gridViews for example. They create a ton of views and show them and that works great.
You cannot add the same object of a view 2 times to a layout. Every object has its own state which in your case in a way says that you will share the state between all your 20 views which doesn't make sense to do, meaning changing the text on one textView will change it on all the rest...
Just inflate 20 seperate views and fill them appropriately.
Also consider using ListView or GridView if you actually have the exact same view it can offer some nice features like view recycling.
You should use ViewHolder patern:
http://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder
it should do all things You want

What is the structure of this layout?

Is this a TableLayout? If it is, how to make this underline under first row and different color per row?
Yes this is the table layout you have to set background color of the table row please refer for following link click here
Assuming it is derived from a ViewGroup (object containing children, for example TableLayout or ListView), it is easy to access all of its children (rows) and do something with it. For example alternating backgrounds:
final int childCount = myGroup.getChildCount();
for(int i = 0; i < childCount; i++) {
View child = myGroup.getChildAt(i);
if(i % 2 == 0) {
child.setBackgroundColor(color1);
} else {
child.setBackgroundColor(color2);
}
}
Same goes for changing the first row, just use myGroup.getChildAt(0) and modify that particular child.
You can use listview with custom item view. Just add header in listview (also footer can be added):
ListView list = (ListView) findViewById(R.id.listView);
View headerView = inflater.inflate(R.layout.header, list, false);
list.addHeaderView(headerView);
Yes it is a Table layout
i have created the similar very easily.
You can also add click events for the text in each row to perform different action.

findViewById to return array of Views

I have the same View inflated (from XML) multiple times. When I call findViewById(R.id.my_layout).setVisibility(View.GONE) I want to apply it on all such views.
How do I do that?
There isn't a version of findViewById() that returns all matches; it just returns the first one. You have a few options:
Give them different ids so that you can find them all.
When you inflate them, store the reference in an ArrayList, like this:
ArrayList<View> mViews = new ArrayList<View>();
Then when you inflate:
LayoutInflater inflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mViews.add(inflater.inflate(R.layout.your_layout, root));
Then when you want to hide them:
for (View v : mViews) { v.setVisibility(View.GONE); }
Depending on what you're doing with these Views, the parent layout may have a way of accessing them. E.g., if you're putting them in a ListView or some such. If you know the parent element you can iterate through the children:
ViewGroup parent = getParentSomehow();
for (int i = 0; i < parent.getChildCount(); ++i) {
View v = parent.getChildAt(i);
if (v.getId() == R.id.my_layout) {
v.setVisibility(View.GONE);
}
}
If the above options don't work for you, please elaborate on why you're doing this.
Modify on the View that holds the inflated layout.
E.g:
If you have
View v = inflater.inflate(.... );
you change the visibility onto this view. v.setVisibility(View.GONE);

Categories

Resources