I have an activity in which my views (table and headertable) are overlapping
private ViewGroup createTable(ViewGroup root) {
// TODO Auto-generated method stub
TableLayout table = new TableLayout(getActivity());
table.setStretchAllColumns(true);
table.setShrinkAllColumns(true);
TableLayout headertable = new TableLayout(getActivity());
headertable.setStretchAllColumns(true);
headertable.setShrinkAllColumns(true);
/* Adding stuff to headertable which contains... */
/* ...table content I DO NOT WANT to scroll*/
root.addView(headertable);
for (int i = -2; i <= 100; i++) {
if (i > 0) {
/*Set up empty views*/
/*...3 empty views will be set*/
}
/* Adding stuff to table which contains... */
/* ...table content I WANT to scroll*/
}
ScrollView sv = new ScrollView(getActivity());
sv.addView(table);
root.addView(sv);
return root;
}
I basically broke a table into headertable and table. I want to scroll table but not headertable. However, my table(which should be below headertable), is overlapping it. Hence, as you can see above I added empty views(so it starts off below headertable(which has three rows)), but realized this would not work. As soon as I scrolled down, the empty views slide up and my headertable gets obstructed again.
All my views have been made programmatically. This activity is a fragment activity.
The XML file contains
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff" >
</FrameLayout>
Any help would be appreciated. Thanks in advance.
I don't know if it's the best way, but here's how I do it:
main.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="vertical" >
<FrameLayout
android:id="#+id/pane"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
header_list.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:layout_alignParentTop="true" />
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="#id/header" />
<TextView
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/header"
android:gravity="center" />
</RelativeLayout>
RecipeListFragment.java
public class RecipeListFragment extends ListFragment {
private TextView header;
private TextView empty;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.common_list, container, false);
header = (TextView) v.findViewById(R.id.header);
empty = (TextView) v.findViewById(android.R.id.empty);
header.setText(R.string.header_recipe);
empty.setText(R.string.empty_recipes);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// List code here
}
}
This code only has a single header line, but you can change that TextView to a TableLayout and then fill it the same way, giving you your header table and putting the list underneath it so that it won't scroll over the top of it.
Hope this helps!
Related
I'm trying to implement ListView inside the new Widget CardView. I want to achieve the same result of Chrome when I do a search on Google. I post you a screen to let you know what I mean.
Screen
As you can see, there are two cards. The results of search are shown in the second card and the scrollbar is not in the card, but outside. In my implementation, instead, the scrollbar is inside card and so the ListView items scroll inside the card!
I post my code:
xml layout (fragment_home.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view_search_2"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
card_view:cardCornerRadius="4dp">
<ListView
android:id="#+id/search_parameters_list"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</android.support.v7.widget.CardView>
</LinearLayout>
Fragment JAVA:
public class HomeFragment extends Fragment
{
private ListView mListView;
private String[] stringValues;
private SearchListItem searchItem;
public HomeFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
final View rootView = inflater.inflate(R.layout.fragment_home, container, false);
mListView = (ListView) rootView.findViewById(R.id.search_parameters_list);
stringValues = getResources().getStringArray(R.array.search_parameters);
parameters = new ArrayList<SearchListItem>();
for(int i = 0; i < stringValues.length; ++i)
{
parameters.add(new SearchListItem(stringValues[i], ""));
}
ListViewSearchAdapter adapter = new ListViewSearchAdapter(getActivity(), parameters);
mListView.setAdapter(adapter);
return rootView;
}
}
Any suggestion to make the same result in the screen? Thanks in advance!
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
I know that there has been simialr questions but I can't make it work even though I look at those. The error message is:
java.lang.RuntimeException: Your content must have a ListView whose id
attribute is 'android.R.id.list'
. I have tried to change the id to list. In another. This what the code looks like:
public class committeeFragment extends SherlockListFragment {
private CommitteeAdapter adapter;
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
adapter = new CommitteeAdapter(getActivity().getApplicationContext());
setListAdapter(adapter);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
return inflater.inflate(R.layout.fragment_committee, container, false);
}
public void
refreshList() {
adapter.updateDataSet();
adapter.notifyDataSetChanged();
}
}
It's using the following adapter:
public class CommitteeAdapter extends BaseAdapter {
private
ArrayList<StudentCommittee> committeeList;
private Context context;
public CommitteeAdapter(Context context) {
this.context = context;
CommitteeDatabaseAdapter dbAdapter = new CommitteeDatabaseAdapter(context);
committeeList = dbAdapter.readAllCommittees();
}
public void updateDataSet() {
CommitteeDatabaseAdapter dbAdapter = new CommitteeDatabaseAdapter(context);
committeeList = dbAdapter.readAllCommittees();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
StudentCommittee committee = committeeList.get(position);
View v = vi.inflate(R.layout.list_item_committee, null);
TextView sectionName = (TextView) v.findViewById(R.id.committee_namn);
sectionName.setText(committee.getName());
return v;
}
#Override
public int getCount() {
return committeeList.size();
}
#Override
public StudentCommittee getItem(int position) {
return committeeList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
}
Here is the xml-file that specifies the list(fragment_committee):
<?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="vertical"
android:tag="#string/tag_fragment_committee"
android:background="#color/white" >
<TextView
style="#style/AppsolutText.Headline"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Festerier" />
<View
android:layout_width="fill_parent"
android:layout_height="2dp"
android:background="#drawable/divider_sliding_menu_item"/>
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
style="#style/AppsolutText.Normal"
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Uppdatera för att se en lista över festerier och fadderier. Kräver internetanslutning."/>
</LinearLayout>
Here is the xml for the list item:
<?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" >
<ImageView
android:id="#+id/committee_symbol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:paddingBottom="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp" />
<TextView
android:id="#+id/committee_namn"
style="#style/AppsolutText.ListHeader"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
I hope that you can figure out what's wrong. I have another listview that has the same id (list) in another xml-file within the project. I don't know if that's a problem. Please help me solve the problem.
The problem is here :
android:id="#+id/list"
you are adding a new id for your ListView but ListFragment needs a default Android ListView Id
change your ListView Id to :
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Change your ListView in XML to have the following id:
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
It's a requirement of using ListFragment/SherlockListFragment
http://developer.android.com/reference/android/app/ListFragment.html
ListFragment has a default layout that consists of a single list view. However, if you desire, you can customize the fragment layout by returning your own view hierarchy from onCreateView(LayoutInflater, ViewGroup, Bundle). To do this, your view hierarchy must contain a ListView object with the id "#android:id/list" (or list if it's in code)
You can try to clean your project. If any xml releted error have , you can find it. Then you can change your list id . Find the list id are exist into your gen folder R.java class.
I decided to stop using actionbarsherlock and use the support libraries instead to get action bar in Android 2.1 and above. After doing this, i got the "java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'". What i did to remedy this problem was
to read this http://developer.android.com/reference/android/app/ListFragment.html#q=fragment
then change my fragment layout file from
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/item_detail"
style="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textIsSelectable="true"
tools:context=".ItemDetailFragment" />
to
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp"
tools:context=".ItemDetailFragment">
<ListView android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FF00"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
<TextView android:id="#+id/item_detail"
style="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textIsSelectable="true"/>
<TextView android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:text="No data"/>
... and voila, the RunTimeException with missing android.R.id.list was gone! Of course, i need to edit my new layout and fix it properly, but the key issue here was that i had overridden the fragment layout in its onCreateView method. ActionBarSherlock DID NOT have a problem with this, but with the Android support library, if u do this, you MUST have a ListView in your XML Layout, with the android:id="#id/android:list" as stated in the info linked to above.
Hope this helps (coming from a total newb in Android app dev)!
I'm very new in Android and I'm bulding a MasterDetailFlow application the problem is that I can't change the layout file (there is only the default TextView).
I want to add an ImageView and a MapView.
Please don't forget that I'm a beginner :D !
Thanks.
public static final String ARG_ITEM_ID = "item_id";
DummyContent.DummyItem mItem;
public StationDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID)) {
mItem = DummyContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_station_detail, container, false);
if (mItem != null) {
((TextView) rootView.findViewById(R.id.station_detail)).setText(mItem.title);
}
return rootView;
}
The auto generated layout files will only contain a textview and you are therefor not able to add any new stull from the palette.
e.g
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="?android:attr/textAppearanceLarge"
android:id="#+id/game_detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".GameDetailFragment" />
If you add any other Layout around the generated stub, you will be able to modify and add new stuff within that layout.xml
example:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/game_detail"
style="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
app:context=".GameDetailFragment" />
</LinearLayout>
Using a LayoutInflater, I am dynamically generating multiple TableRows, each which contains a checkbox. Everything worked great until you rotated the display. Each CheckBox gets the same text and checked state as the very last CheckBox created.
I found that if I assigned a unique ID to each row and to each checkbox it works correctly (each checkbox keeps its unique text and checked state).
If inflating the same layout multiple times, Do I need to assign a unique ID to every View inside the inflated layout? That sure could be a pain if you have an involved layout that is being inflated.
Here is my code that works:
main activity
public class PrototypeActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
TableLayout tablesLayout = (TableLayout)findViewById(R.id.TableLayout1);
tablesLayout.removeAllViews();
String[] values = new String[] { "Item 1", "Item 2", "Item 3"};
for (int i = 0; i < values.length; i++) {
View view = inflater.inflate(R.layout.row_layout, null, false);
view.setId(i);
CheckBox checkBox = (CheckBox) view.findViewById(R.id.tableCollectCheckBox);
checkBox.setId(values.length+i);
checkBox.setText(values[i]);
tablesLayout.addView(view);
}
tablesLayout.invalidate();
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TableLayout
android:id="#+id/TableLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"/>
</LinearLayout>
</ScrollView>
</FrameLayout>
row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<TableRow
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal">
<CheckBox
android:id="#+id/tableCollectCheckBox"
android:text="DataTable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</TableRow>
You should call checkBox.setFreezesText(true).