Memory issue on creating dynamic view inside RecyclerView - android

I am creating UI layout dynamically inside the RecyclerView which causes out of memory issue when the application is used for long time.Ui being re created on scrolling up and down. How can i prevent the creation of views on scrolling? my code looks as follows.
LinearLayout container = (LinearLayout) getBaseView().findViewById(R.id.container);
container.removeAllViews();
int position = 0;
for (int i= 0; i<content.size()/2;i ++) {
LinearLayout ln = new LinearLayout(getBaseView().getContext());
ln.setWeightSum(2);
ln.setGravity(Gravity.CENTER);
for (int j = 0; j<COLUMN_COUNT; j++) {
VIOPlayListItemView tile = new VIOPlayListItemView(getBaseView().getContext());
tile.setTag(position);
tile.setGravity(Gravity.CENTER);
ln.addView(tile);
if (position <content.size()) {
tile.setData(content.get(position));
}
position ++;
}
container.addView(ln);
}
}

Related

Android: add an array of Switches in a LinearLayout

I want to add some switches in a linear layout (declared as a view, not as a LinearLayout). I tried this, but it gets me an error:
numberDevices = 3; //This is going to be used after
Switch[] switches = new Switch[numberDevices];
for (int i = 0; i < numberDevices; i++) {
switches[i].setTextOn("ON");
switches[i].setTextOff("OFF");
switches[i].setId(i);
((LinearLayout) linearLayout).addView(switches[i]);
}
Any idea?
You haven't created any Switches, you've just made an empty array. You need to create the switches first:
for (int i = 0; i < numberDevices; i++) {
switches[i] = new Switch(linearLayout.getContext());
...
}

Creating a GridView-like layout in Android without using GridView

So I'm trying to create a GridView style layout in Android without actually using a custom Gridview adapter, since I don't want it to scroll. I've tried just turning scrolling off, but it ruins my layout since I'm adding other elements around it in a vertical LinearLayout.
My next experiment was to use a TableLayout and then just add inflated layouts as table cells, but I'm also having an issue with this. Here is a test that I am running for a brief proof of concept:
TableRow trackingActivityRow = new TableRow(getActivity());
for(int j = 0; j < trackingActivities.size(); j ++) {
TrackingActivity trackingActivity = trackingActivities.get(j);
View trackingActivityCell = getActivity().getLayoutInflater()
.inflate(R.layout.table_cell_tracking_activity, trackingActivityRow, true);
TextView txtDescription = (TextView)trackingActivityCell.findViewById(R.id.txtDescription);
txtDescription.setText(trackingActivity.getDescription());
}
tableLayout.addView(trackingActivityRow);
It seems to create the number of cells correctly, but it doesn't want to set the text like it should be. Furthermore, I'm having an issue of logic when it comes to creating a new row for every 4 TrackingActivities.
If anyone has any input it would be appreciated.
/Update/
Here is a graphic of the issue. The cell with "Walk" in it is displaying correctly, but the other cells only display the placeholder text inside the textview which should have been replaced.
I created a customized GridView based on a tablelayout with a listadapter.
Simplified version of the setAdapterMethod in the extended TableLayout:
int itemPos = -1;
int numRows = (int) Math.ceil((double) adapter.getCount() / (double) mNumColumns);
for (int yPos = 0; yPos < numRows; yPos++) {
//Create new row
TableRow tableRow = new TableRow(this.getContext());
for (int xPos = 0; xPos < mNumColumns; xPos++) {
itemPos++;
View itemView = adapter.getView(itemPos, null, tableRow);
tableRow.addView(itemView);
}
this.addView(tableRow, new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT));
}

Unable to refresh custom view in Layout

In my onCreateView i have the following codes to populate custom view into my LinearLayout whereby StageViewer extends View.
layout = (LinearLayout)rootView.findViewById(R.id.lo1);
for (int i = 0 ; i < 6 ; i ++)
{
StageViewer viewer = new StageViewer(i,callingActivity,this, 0, Global.STAGE_VIEW);
layout.addView(viewer);
stageList.add(viewer);
}
In my application the user have a option to set all view to default mode
public void resetToDefault()
{
for (int i = 0 ; i < 6 ; i ++)
{
StageViewer viewer = new StageViewer(i,callingActivity,this, 0, Global.STAGE_VIEW);
layout.addView(viewer);
stageList.add(viewer);
}
}
However upon reset the new view are NOT viewable (an empty layout is shown).
I tried
viewer.invalidate();
layout.refreshDrawableState();
Did I miss out something ?
public void resetToDefault()
{
layout.removeAllViews();
stageList.clear();
for (int i = 0 ; i < 6 ; i ++)
{
StageViewer viewer = new StageViewer(i,callingActivity,this, 0, Global.STAGE_VIEW);
layout.addView(viewer);
stageList.add(viewer);
}
}
Maybe layout params are missing?
LinearLayout.LayoutParams layoutParams =
new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
viewer.setLayoutParams(layoutParams);
layout.addView(viewer);

Counting visible elements in a layout

Suppose in my LinearLayout (say parentLayout) there are 5 other LinearLayouts (say childLayout), where only one of them are visible at the moment. The other layouts depend on some external event to make them visible. How do I count the number of childLayout in the parentLayout that are visible ?
You can iterate over the children of the parent layout and check their visibility. Something like this:
LinearLaout parent = ...;
int childCount = parent.getChildCount();
int count = 0;
for(int i = 0; i < childCount; i++) {
if(parent.getChildAt(i).getVisibility() == View.VISIBLE) {
count++;
}
}
System.out.println("Visible children: " + count);
here is a funntion that returns number of visible childs in ViewGroup like LinearLayout, RelativeLayout, ScrollView, ..etc
private int countVisible(ViewGroup myLayout)
{
if(myLayout==null) return 0;
int count = 0;
for(int i=0;i<myLayout.getChildCount();i++)
{
if(myLayout.getChildAt(i).getVisibility()==View.VISIBLE)
count++;
}
return count;
}
If you are using Kotlin just use extention:
fun LinearLayout.visibleChildCount(): Int {
var childVisible = 0
children.iterator().forEach {
if(it.isVisible) ++childVisible
}
return childVisible
}

Get all TableRow's in a TableLayout

I've been looking for hours on how to get all TableRow's in a TableLayout. I already know how to add and delete rows dynamically, but I need to loop over all the rows and selectively delete some of them.
I think I can come up with a work around, but I'm trying to avoid crude hacks in my app.
Have you tried using getChildCount() and getChildAt(int) respectively?
Should be fairly easy in a loop:
for(int i = 0, j = table.getChildCount(); i < j; i++) {
View view = table.getChildAt(i);
if (view instanceof TableRow) {
// then, you can remove the the row you want...
// for instance...
TableRow row = (TableRow) view;
if( something you want to check ) {
table.removeViewAt(i);
// or...
table.removeView(row);
}
}
}
if you have other type view
TableLayout layout = (TableLayout) findViewById(R.id.IdTable);
for (int i = 0; i < layout.getChildCount(); i++) {
View child = layout.getChildAt(i);
if (child instanceof TableRow) {
TableRow row = (TableRow) child;
for (int x = 0; x < row.getChildCount(); x++) {
View view = row.getChildAt(x);
view.setEnabled(false);
}
}
}
I have been looking for the same thing for a while. For me, I was looking to how to check views in my table layout. I did this by:
//This will iterate through your table layout and get the total amount of cells.
for(int i = 0; i < table.getChildCount(); i++)
{
//Remember that .getChildAt() method returns a View, so you would have to cast a specific control.
TableRow row = (TableRow) table.getChildAt(i);
//This will iterate through the table row.
for(int j = 0; j < row.getChildCount(); j++)
{
Button btn = (Button) row.getChildAt(j);
//Do what you need to do.
}
}
If you try to remove TableRows the ID Counter will decrease so pls use this loop for removing ... else if you dont want to remove you can use some of the loops above :D
TableLayout table = (TableLayout) findViewById(R.id.tblScores);
for(int i = 0; i < table.getChildCount(); i = 0)
{
View child = table.getChildAt(0);
if (child != null && child instanceof TableRow)
{
TableRow row = (TableRow) child;
row.removeAllViews();
table.removeViewAt(i);
}
}
This clears all rows!
I think your main problem is if you remove rows that all rows will be newly placed so that the row with the ID = 5 is now ID = 4 if you delete the row with ID = 3
so maybe you have to reset the counter and iterate again or you generate the table new after you cleared all rows
for(int i = 0, j < table.getChildCount(); i < j; i++){
// then, you can remove the the row you want...
// for instance...
TableRow row = (TableRow) table.getChildAt(i);
if( something you want to check ) {
removeViewAt(i);
// or...
removeView(row);
}
}

Categories

Resources