Fragment Width issue in LinearLayout inside HorizontalscrollView - android

I have a Horizontalscrollview inside which is horizontal LinearLayout.
I tried to add Fragments dynamically into the Linear Layout. Although I set my fragment width as "match_parent", the fragment is not filling in the screen width.
Here's my xml layouts for MainActivity
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="400dp"
android:fillViewport="true"
android:id="#+id/baseScrollView">
<LinearLayout
android:id="#+id/scrollViewLayout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
</HorizontalScrollView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnNext"
android:text="Next Page"/>
</LinearLayout>
Here's my code for MainActivity
Button btnNext;
CustomHorizontalScrollView baseScrollView;
LinearLayout scrollViewLayout;
boolean isFragment1Added = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnNext = (Button) findViewById(R.id.btnNext);
scrollViewLayout = (LinearLayout) findViewById(R.id.scrollViewLayout);
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(isFragment1Added){
isFragment1Added = false;
addCustomFragment(new Fragment2(), "fragment_2");
}else{
isFragment1Added = true;
addCustomFragment(new Fragment1(), "fragment_1");
}
}
});
}
public void addCustomFragment(Fragment fragmentView, String tag) {
FragmentTransaction viewTransaction = getFragmentManager().beginTransaction();
viewTransaction.add(R.id.scrollViewLayout, fragmentView, tag);
viewTransaction.commit();
}
Here's fragment1.xml. fragment2 is similar to fragment1.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_red_dark"
tools:context="com.uobtravelplanners.horizontalscrollviewtest.Fragment1">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="FRAGMENT 1"
android:textSize="50sp"
android:gravity="center"/>
</FrameLayout>
here's the screenshot

set the layout_width of scrollViewLayout to wrap_content
set the fragment's width to screen width by programmatically
Edit 1
Get screen dimensions in pixels
first, get the screen width according to this post.
then set the layout_width in onCreateView method like
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
// get screen width
int screenWidth = ...
// get the root view of the fragment
View root = inflater.inflate(R.id.your_layout, container, false);
// set layout_width through LayoutParams
root.setLayoutParams(new ViewGroup.LayoutParams(screenWidth, ViewGroup.LayoutParams.MATCH_PARENT));
return root;
}

Related

setOnClickListener in RelativeLayout not working

I have a structure in my android application
LinearLayout > FrameLayout >ImageView(used as a FrameLayout
Background) & RelativeLayout > TextView & ImageView.
I need that when I click in the FrameLayout or RelativeLayout or FirstImageView ( because it is the Bigger Zone , the textView or 2nd Image view are small ) do an action.
I tried to add setOnClickListener to this item but didn't work.
This is my Code:
public class HomeFragment extends Fragment {
View rootView;
public HomeFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.home_fragment, container, false);
RelativeLayout paleoFoodBackGround = (RelativeLayout) rootView.findViewById(R.id.relativeLytPaleoFoodHome);
paleoFoodBackGround.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("1FOOD_LIST", "onClick: ");
}
});
return rootView;
}
public void clickFood(){
Log.d("2FOOD_LIST", "onClick: ");
}
}
This is my Layout structure:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="50"
android:orientation="vertical"
android:paddingLeft="2.5dp"
android:paddingRight="5dp"
android:weightSum="100">
<FrameLayout
android:id="#+id/framePaleoFoodHome"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="50"
android:paddingBottom="2.5dp">
<ImageView
android:id="#+id/imgViewPaleoFoodBackGround"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:scaleType="center"
app:srcCompat="#drawable/recipes" />
<RelativeLayout
android:id="#+id/relativeLytPaleoFoodHome"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<ImageView
android:id="#+id/imgViewRecipesIconHome"
style="#style/iconHome"
app:srcCompat="#drawable/cooking"
/>
<TextView
android:id="#+id/txtViewRecipesTxtHome"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/textViewHomeSquare"
android:text="#string/RecipesHome"
android:layout_below="#id/imgViewRecipesIconHome"/>
</RelativeLayout>
</FrameLayout>
<Framelayout> .... </Framelayout>
</LinearLayout>
I recommend using ImageButton instead of image. Also set your RelativeLayout to have android:clickable="true". Also set all children views that are not clickable with android:clickable="false"

how to set inflate layout center which added dynamically in linear layout Android

I am adding inflate layout dynamically in linear layout,i need to set layout center based on number of layouts.suppose if layouts are two , then it start showing from center.
following is my xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<HorizontalScrollView
android:id="#+id/hsv_category_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:scrollbars="none">
<LinearLayout
android:id="#+id/ll_placeHolder"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>
and following are my class
public class ScrollTest extends Activity {
HorizontalScrollView hsv_category_list;
LinearLayout ll_placeHolder;
View layoutView[];
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scroll_test);
hsv_category_list = (HorizontalScrollView)
findViewById(R.id.hsv_category_list);
ll_placeHolder = (LinearLayout) findViewById(R.id.ll_placeHolder);
layoutView = new View[2];
for (int i = 0; i < 2; i++) {
layoutView[i] =
LayoutInflater.from(this).inflate(R.layout.category_list_item, null);
layoutView[i].setId(i);
View parent = layoutView[i].findViewById(i);
TextView tvTime = (TextView)
parent.findViewById(R.id.tv_arrival_time);
tvTime.setText("" + i);
ll_placeHolder.setGravity(Gravity.CENTER);
ll_placeHolder.addView(layoutView[i]);
}
}
}
i need to set the inflate layout start from center.
Please help me to solve this.Thank you.
Set layout gravity to center_horizontal in xml file like this
<LinearLayout
android:id="#+id/ll_placeHolder"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:gravity="center_horizontal"
android:layout_gravity="center"
android:orientation="horizontal">
</LinearLayout>

Have two LinearLayouts have equal height using layout_weight, not working

I am having difficulty getting these two LinearLayouts nested in a single LinearLayout to have equal height. The first LinearLayout has 0 height while the second takes up the entire screen.
Not sure if it's important but I programmatically populate the second LinearLayout with buttons.
XML
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.yako.mimibot.pages.RemoteCtrlFragment">
<LinearLayout
android:id="#+id/remote_ctrl_ll"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="2">
<LinearLayout
android:id="#+id/terminal_ll"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#drawable/terminal_window">
<ScrollView
android:id="#+id/terminal_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/terminal_rl"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
</ScrollView>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="#+id/remote_gesture_btns_ll"
android:gravity="center">
</LinearLayout>
</LinearLayout>
</FrameLayout>
Code For Populating Second LinLay (R.id.remote_gesture_btns_ll)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_remote_ctrl, container, false);
mRemoteGestureBtnsLL = (LinearLayout) view.findViewById(R.id.remote_gesture_btns_ll);
mTerminalRL = (RelativeLayout) view.findViewById(R.id.terminal_rl);
String[] mimiGestures = getActivity().getResources().getStringArray(R.array.mimi_capable_gestures_array);
LinearLayout mimiBtnsLL = null;
Button mimiBtn;
for (int i=0; i < mimiGestures.length; i++) {
if (i%2 == 0) {
mimiBtnsLL = new LinearLayout(getActivity());
mimiBtnsLL.setOrientation(LinearLayout.HORIZONTAL);
mimiBtnsLL.setGravity(Gravity.CENTER_HORIZONTAL);
mimiBtnsLL.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
mimiBtn = new Button(getActivity());
mimiBtn.setText(mimiGestures[i]);
mimiBtn.setHeight(100);
mimiBtn.setWidth(200);
mimiBtn.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
mimiBtnsLL.addView(mimiBtn);
if (i%2 == 1) {
mRemoteGestureBtnsLL.addView(mimiBtnsLL);
}
}
return view;
}
Just set the height of parent LinearLayout (with id remote_ctrl_ll ) to match_parent.
You're setting the weight & height explicitly on your first nested LinearLayout. try setting the height explicitly on your Root LinearLayout, and use ONLY layout_weights for the nested LinearLayouts

How to programatically add multiple Fragments to activity in android

I am trying to display 6 rows inside a linear layout. I want to do this through fragments as the content will be dynamic and the number of rows will also be dynamic later on. I have the following code but only one row appears on the screen. I have SettingsActivity.java, settings.xml ThemeRowFragment,java and theme_row_layout.xml.
SettingsActivity.java
//imports
public class SettingsActivity extends FragmentActivity {
private int NUM_THEMES = 7;
ThemeRowFragment[] view_themes;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
view_themes = new ThemeRowFragment[NUM_THEMES];
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
for (int i = 0; i < view_themes.length; i++) {
view_themes[i] = new ThemeRowFragment(COLOR_MAP[i]);
fragmentTransaction.add(R.id.theme_linear_layout, view_themes[i],
"Row" + i);
}
fragmentTransaction.commit();
}
}
settings.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:id="#+id/theme_linear_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/string_theme"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/string_theme"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#cde21c" />
</LinearLayout>
ThemeRowFragment.java
public class ThemeRowFragment extends Fragment {
private int[] colors;
public ThemeRowFragment(int colors[]) {
super();
this.colors = colors;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.theme_row_layout, container,
false);
return view;
}
}
theme_row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/pick_colors" >
</TextView>
</LinearLayout>
Fragments will inflate themselves into the View you add them to. So you really can't do it this way. So you need to have X empty containers, one for each fragment you are going to inflate. Add each fragment to the same container will actually layer them all on top of each other, sort of making them really hard to see and use when the screen renders.
Alternatives:
You could do something like the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:id="#+id/theme_linear_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/string_theme"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/string_theme"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#cde21c" />
<FrameLayout android:id="#+id/fragment_container1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container2"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container3"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container4"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#+id/fragment_container5"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<!-- etc. -->
</LinearLayout>
Or just add each FrameLayout programatically via the LinearLayout's addView() with a unique ID for each FrameLayout.
LinearLayout layout = (LinearLayout)findViewById(R.id.linear);
FragmentTxn txn = getFragmentManager.beginTransaction();
int i = 1; // This seems really fragile though
for (Fragment f : fragments) {
FrameLayout frame = new FrameLayout(this);
frame.setId(i);
layout.addView(frame);
txn.add(i, f);
i++;
}
txn.commit();
Or the other way would be to just use a listView and add each row that way. Not using Fragments at all.
<TextView
android:id="#+id/string_theme"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/string_theme"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#cde21c" />
<ListView android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
then later on do something like this:
ListView view = (ListView)findViewById(R.id.listview);
view.setAdapter(new ArrayAdapter(items) { // items is a collection of objects you are representing
public View getView(int position, View view, ViewGroup parent) {
view = LayoutInflator.from(parent.getContext()).inflate(R.layout.theme_row_layout, parent, false);
// manipulate the view
return view;
});
You are creating a instance of ThemeRowFragment n number of times. The problem is you are creating this as an fragment and trying to add it dynamically. Since you instantiate the same Fragment i suggest you to use ListView and use a custom adapter and set CustomView and override the getView method of your adapter to adjust your views

Dynamically include another layout in Fragment Activity

This is my Home.xml layout file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rellay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/placesgradient">
<Button
android:id="#+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="click"
/>
**<I want to include another layout here on a click of a button dynamically on click of a button >**
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_below="#id/btn2"
android:text="hello this is text..see above" />
</RelativeLayout>
This is my Home.java file
public class Home extends Fragment implements OnClickListener {
Button b1;
RelativeLayout r1;
View rootView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.home, container, false);
b1 = (Button) rootView.findViewById(R.id.btn2);
b1.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View arg0) {
ViewGroup con = null;
r1 = (RelativeLayout) rootView.findViewById(R.id.rellay);
LayoutInflater layoutInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
r1.addView(layoutInflater.inflate(R.layout.test1, con , false));
}
}
When I click on the button it places the test1.xml layout file at the top of the home.xml layout. I need it to be between the button and the text. I checked this code on stack before but it doesn't seem to work with the FragmentActivity. Here 1 indicates the index or the second child in this case.
rl.addView(1, layoutInflater.inflate(R.layout.content_layout, this, false) );
How can I achieve it? Help!!
I would put some container view at the position you want your layout to be like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rellay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/placesgradient">
<Button
android:id="#+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="click"
/>
<FrameLayout
android:id="#+id/flContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_below="#id/btn2"
android:text="hello this is text..see above" />
</RelativeLayout>
Then you can retrieve the container in your Fragment like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.home, container, false);
// Retrieve your container
flContainer = rootView.findViewById(R.id.flContainer);
b1 = (Button) rootView.findViewById(R.id.btn2);
b1.setOnClickListener(this);
return rootView;
}
And later when you want to add your layout you can add a child to the FrameLayout like this:
flContainer.addView(subLayout);
If you later want to change the layout in your container you can do it like this:
flContainer.removeAllViews();
flContainer.addView(otherLayout);
Use LayoutParams.
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, R.id.btn2);
r1.addView(layoutInflater.inflate(R.layout.test1, con , false),params);
Or put the view in your layout and toggle visibility with View.setVisibility(View.GONE/View.VISIBLE)

Categories

Resources