move button to the next line when there is no - android

I need to implement menu that can't be GridView or ListView. Items are next to each other and if there is no place, items should be display in next line as is visible on picture
I started implementation that is based on SpannableString and ReplacementSpan, but it supports only basic styling and I have problem with selected state.
What's the best way to implement such menu?

Maybe this will help you
/**
* Copyright 2011 Sherif
* Updated by Karim Varela to handle LinearLayouts with other views on either side.
* #param linearLayout
* #param views : The views to wrap within LinearLayout
* #param context
* #param extraView : An extra view that may be to the right or left of your LinearLayout.
* #author Karim Varela
**/
private void populateViews(LinearLayout linearLayout, View[] views, Context context, View extraView)
{
extraView.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// kv : May need to replace 'getSherlockActivity()' with 'this' or 'getActivity()'
Display display = getActivity().getWindowManager().getDefaultDisplay();
linearLayout.removeAllViews();
int maxWidth = display.getWidth() - extraView.getMeasuredWidth() - 20;
linearLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams params;
LinearLayout newLL = new LinearLayout(context);
newLL.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
newLL.setGravity(Gravity.LEFT);
newLL.setOrientation(LinearLayout.HORIZONTAL);
int widthSoFar = 0;
for (int i = 0; i < views.length; i++)
{
LinearLayout LL = new LinearLayout(context);
LL.setOrientation(LinearLayout.HORIZONTAL);
LL.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
LL.setLayoutParams(new ListView.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
views[i].measure(0, 0);
params = new LinearLayout.LayoutParams(views[i].getMeasuredWidth(), LayoutParams.WRAP_CONTENT);
params.setMargins(5, 0, 5, 0);
LL.addView(views[i], params);
LL.measure(0, 0);
widthSoFar += views[i].getMeasuredWidth();
if (widthSoFar >= maxWidth)
{
linearLayout.addView(newLL);
newLL = new LinearLayout(context);
newLL.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
newLL.setOrientation(LinearLayout.HORIZONTAL);
newLL.setGravity(Gravity.LEFT);
params = new LinearLayout.LayoutParams(LL.getMeasuredWidth(), LL.getMeasuredHeight());
newLL.addView(LL, params);
widthSoFar = LL.getMeasuredWidth();
}
else
{
newLL.addView(LL);
}
}
linearLayout.addView(newLL);
}

I finally discovered library called Android flow layout that works well https://github.com/ApmeM/android-flowlayout

Related

Change button width and height through code

I am trying to change the width and height of Buttons I dynamically create but my code below is not working. The Buttons stays the same default size. Anyone know why this is not working?
I believe it might have to do with this line:
myButton.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
The problem may be that I am not supposed to create new LinearLayout params each time but rather add it to an existing LayoutParam?
What do you guys think?
public void onClick(View view)
{
LinearLayout linearLayout2 = new LinearLayout(view.getContext());
linearLayout2.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams rlp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
int size = enter_txt.getText().toString().length();
for (int i=0; i<size; i++){
Button myButton = new Button(view.getContext());
myButton.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
myButton.setWidth(100);
myButton.setHeight(100);
myButton.setBackgroundResource(R.drawable.button);
linearLayout2.addView(myButton, rlp);
}
}
Change this code :
myButton.setWidth(100);
myButton.setHeight(100);
To this :
myButton.getLayoutParams().width = 100;
myButton.getLayoutParams().height = 100;
And yes, in your case you can replace :
myButton.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
To :
myButton.setLayoutParams(rlp);
You can use other constructor of the LinearLayout.LayoutParams, which receiving width and height:
myButton.setLayoutParams(new LinearLayout.LayoutParams(100, 100));

Arrange RelativeLayout below another dynamically

I'm trying to dynamically build relative layouts consisting of an image and a textview at the moment. I have tried building a loop to place the next relative layout below the former one, but I can't really make it work. The end result should be something like this, but I guess that if i figure out how to align below the former one, I can also figure out how to place it right_of the former relative layout.
Any suggestions? This is my code so far:
RelativeLayout container1 = (RelativeLayout) rootView
.findViewById(R.id.main_layout);
for (int i = 0; i < pictures.size(); i++) {
RelativeLayout tile = new RelativeLayout(getActivity());
tile.setId(i);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.height = height / 3;
params.width = width / 2;
tile.setLayoutParams(params);
ImageButton ibGood = new ImageButton(getActivity());
ibGood.setId(1);
ibGood.setImageResource(pictures.get(0));
ibGood.setAdjustViewBounds(true);
ibGood.setMaxHeight(height / 3 / 5 * 4);
ibGood.setMaxWidth(width);
ibGood.setScaleType(ScaleType.CENTER_CROP);
ibGood.setPadding(5, 5, 5, 5);
tile.addView(ibGood);
RelativeLayout.LayoutParams tvPriceParam = new RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
tvPriceParam.addRule(RelativeLayout.BELOW, ibGood.getId());
tvPriceParam.addRule(RelativeLayout.ALIGN_LEFT, ibGood.getId());
TextView tvPrice = new TextView(getActivity());
tvPrice.setId(2);
tvPrice.setHeight(tile.getHeight() / 5);
tvPrice.setWidth(tile.getWidth() / 5 * 2);
tvPrice.setPadding(5, 0, 0, 5);
tvPrice.setText(Integer.toString(price.get(0)));
tile.addView(tvPrice, tvPriceParam);
if (counter == 0) {
container1.addView(tile);
} else if (counter % 2 == 0) {
RelativeLayout.LayoutParams lay = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
lay.addRule(RelativeLayout.BELOW, -1);
tile.setLayoutParams(lay);
container1.addView(tile);
}
counter += 1;
}
you can make it with the custom gridview !! why you are doing this with the relative layout ?
here is the link which you can use to achieve what do you want..
http://www.learn-android-easily.com/2013/09/android-custom-gridview-example.html
http://www.caveofprogramming.com/uncategorized/custom-gridview-with-imageview-and-textview-in-android/
please visit 3 links are there you will get that you want .. with relative layout ..
Thanks,
Madhav

Multi row view with uneven columns, data from adapter

I'm trying to create a view that would take data from an adapter and distribute it next to each other in rows. The view should rely on its width to decide when to put elements in next row. Please have a look on the ilustration, of what I'm trying to achieve.
http://i43.tinypic.com/2w327bq.png
I've found some great code here: Android - multi-line linear layout It generates linear layouts dynamically (puts horizontal layouts inside of an vertical layout). However, I would like to keep all this data in a single view and set an adapter on it. I would be grateful for any suggestions on how to achieve this.
Code snippet from quoted thread:
/**
* Copyright 2011 Sherif
* Updated by Karim Varela to handle LinearLayouts with other views on either side.
* #param linearLayout
* #param views : The views to wrap within LinearLayout
* #param context
* #param extraView : An extra view that may be to the right or left of your LinearLayout.
* #author Karim Varela
**/
private void populateViews(LinearLayout linearLayout, View[] views, Context context, View extraView)
{
extraView.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// kv : May need to replace 'getSherlockActivity()' with 'this' or 'getActivity()'
Display display = getSherlockActivity().getWindowManager().getDefaultDisplay();
linearLayout.removeAllViews();
int maxWidth = display.getWidth() - extraView.getMeasuredWidth() - 20;
linearLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams params;
LinearLayout newLL = new LinearLayout(context);
newLL.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
newLL.setGravity(Gravity.LEFT);
newLL.setOrientation(LinearLayout.HORIZONTAL);
int widthSoFar = 0;
for (int i = 0; i < views.length; i++)
{
LinearLayout LL = new LinearLayout(context);
LL.setOrientation(LinearLayout.HORIZONTAL);
LL.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
LL.setLayoutParams(new ListView.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
views[i].measure(0, 0);
params = new LinearLayout.LayoutParams(views[i].getMeasuredWidth(), LayoutParams.WRAP_CONTENT);
params.setMargins(5, 0, 5, 0);
LL.addView(views[i], params);
LL.measure(0, 0);
widthSoFar += views[i].getMeasuredWidth();
if (widthSoFar >= maxWidth)
{
linearLayout.addView(newLL);
newLL = new LinearLayout(context);
newLL.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
newLL.setOrientation(LinearLayout.HORIZONTAL);
newLL.setGravity(Gravity.LEFT);
params = new LinearLayout.LayoutParams(LL.getMeasuredWidth(), LL.getMeasuredHeight());
newLL.addView(LL, params);
widthSoFar = LL.getMeasuredWidth();
}
else
{
newLL.addView(LL);
}
}
linearLayout.addView(newLL);
}

May I reuse LayoutPrams with ViewGroup.addView?

Does ViewGroup.addView clones LayoutParams data into inside or links to it? May I reuse the same instance of LayoutParams with multiple calls to addView() with different views?
There is nothing about it in apidoc.
WOW
The answer is NO (checked experimentally):
public class SymbolPadActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout.LayoutParams labelParams;
/*
* This block to reuse is not working
labelParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
labelParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
labelParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
*/
RelativeLayout mover = new RelativeLayout(this);
TextView textView;
for(int leftMargin = 0; leftMargin<3000; leftMargin += 100) {
for(int topMargin=0; topMargin<800; topMargin += 40) {
// I can't omit these 3 lines
labelParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
labelParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
labelParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
labelParams.leftMargin = leftMargin;
labelParams.topMargin = topMargin;
textView = new TextView(this);
textView.setText("(" + leftMargin + "," + topMargin + ")");
mover.addView(textView, labelParams);
}
}
RelativeLayout.LayoutParams moverParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
moverParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
moverParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
moverParams.leftMargin = 0;
moverParams.topMargin = 0;
RelativeLayout stator = new RelativeLayout(this);
stator.addView(mover, 0, moverParams);
setContentView(stator);
}
}
There is nothing about it in apidoc.
This means you need to make the more conservative choice, no matter what the current implementation is, as the implementation could change.
Hence, you need to assume that it is not safe to reuse an instance of LayoutParams with different Views.
For what it's worth, as far as I can tell, that is true anyway - ViewGroup doesn't make a copy.
This is an old question, but there seems to be an updated answer:
The LayoutParams has a constructor for copying another
Source: http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html
ViewGroup.LayoutParams(ViewGroup.LayoutParams source)
This would suggest not to re-use it, but perhaps to create 1 layout params object with everything you need, then just call
new LayoutParams(someLayoutParamsToReUse)
In my case, I wanted to set the layout params of a button to be the same as another button. I initially tried:
button.setLayoutParams(button2.getLayoutParams());
This will not work, however this should:
button.setLayoutParams(new LayoutParms(button2.getLayoutParams))'

Android: programmatically creating two columns in a table

showtimeTable = new TableLayout(this);
showtimeTable.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
for(int i=0;i<object.dateList.size();i++){
/* Create a new row to be added. */
TableRow tr = new TableRow(this);
tr.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
/* Create testview to be the row-content. */
mytext = new TextView(this);
mytext.setText(object.dateList.get(i).getTextDate());
mytext.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
mytext.setTextAppearance(this, R.style.detaileventDate);
tr.addView(mytext);
time = new TextView(this);
time.setText(object.dateList.get(i).getTime());
time.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
time.setTextAppearance(this, R.style.detaileventTime);
tr.addView(time);
/* Add row to TableLayout. */
showtimeTable.addView(tr,new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
layout.addView(showtimeTable);
I have this table all setup, but the two textfields are hugging each other. What I want to achieve is the appearance of two columns and have the time textfield on the right side.
I tried changing the margins in their respective Styles but that doesnt affect it.
I think you should use padding here. It will make padding of the Text view inside the table row. I have tried to do it with your code and just added some test lines:
mytext.setPadding(20, 3, 20, 3);
time.setPadding(20, 3, 20, 3);
It worked fine. Moreover, you can use "Gravity" for your purposes. See and example here: http://developer.android.com/resources/tutorials/views/hello-tablelayout.html
Table layout does not have concept of columns but you can add multiple views in table row by defining different width of those views.
Following code will specify size of column depending on specified colSpan value.
int COL_COUNT=2;
int mScreenWidthInDp = getScreenWidthInDip(activityContext);
private View getColumnItem(String colText, int colSpan) {
View view = mActivity.getLayoutInflater().inflate(R.layout.table_column_view, null);
TextView textView = (TextView) view.findViewById(R.id.tablet_title);
textView.setText(colText);
int columnWidth = (mScreenWidthInDp / COL_COUNT) * span;
TableRow.LayoutParams params = new TableRow.LayoutParams(columnWidth, ViewGroup.LayoutParams.WRAP_CONTENT, 1);
params.span = colSpan;
view.setLayoutParams(params);
return view;
}
public static int getScreenWidthInDip(Activity context) {
if (mScreenWidthInDp == 0) {
WindowManager wm = context.getWindowManager();
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
int screenWidth_in_pixel = dm.widthPixels;
float screenWidth_in_dip = screenWidth_in_pixel / dm.density;
mScreenWidthInDp = (int) screenWidth_in_dip;
}
return mScreenWidthInDp;
}
you can set layout weight parameter for the table row. This will arrange the childrens accordingly.
mytext.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT,1f));
The final parameter is the layout weight

Categories

Resources