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!
Related
I'm trying to find same problem but I don't found anything similar. My problem is:
I have a listFragment that get the data from the sqlite. All works fine but when the listview have more elements and I need to do a scroll to see more elements, the view have a rare behaviour. I can see in the view how all the elements are static but in the behind of the view all the elements are doing scroll.
I add a picture to see better the behaviour.
This is my listFragment class:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dataBase = new DataBaseWrapper(getActivity());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = null;
final String[] name;
final String[] url;
dataBase.getAllData();
name = new String[dataBase.getAllData().size()];
url = new String[dataBase.getAllData().size()];
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
Map<String, String> map;
for (int i = 0; i < dataBase.getAllData().size(); i++) {
name[i] = dataBase.getAllData().get(i).getName();
url[i] = dataBase.getAllData().get(i).getUrl();
map = new HashMap<String, String>();
map.put("name", name[i]);
map.put("url", url[i]);
list.add(map);
}
rootView = (ViewGroup) inflater.inflate(R.layout.fragment_listview, container, false);
SimpleAdapter adapter = new SimpleAdapter(getActivity(), list, R.layout.favourites, new String[] { "name", "url" }, new int[] { R.id.newspaperNameFavourite, R.id.passUrl });
setListAdapter(adapter);
setRetainInstance(true);
return rootView;
}
Fragment_Listview xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/favourites_fragment">
<ListView android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:layout_marginTop="50dp"/>
</FrameLayout>
Favourites xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="45dp"
android:padding="5dp">
<TextView
android:id="#+id/newspaperNameFavourite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="#+id/passUrl"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="135dp"
android:layout_marginEnd="135dp"
android:visibility="gone"/>
</RelativeLayout>
This is where I create the fragmentList:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview);
Fragment fr = new FavouritesActionBar();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.commit();
}
listview xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:name="com.exagon.goalnews.favourites.FavouritesActionBar"
android:id="#+id/the_actual_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
I have to change my answer. I don't think the ListView is duplicated. Either version of the fragment creation code should work fine. I think the problem is that your Fragment is duplicated.
I didn't look carefully enough at listview.xml. You already declared a FavouritesActionBar fragment in listview.xml, yet in your code you create another one and are trying to replace the declared one. This is redundant.
I remember seeing some comments about how it's not good to mix XML-declared fragments with coded fragments. I can't find the reference to that, but I can tell you that every time I've tried to do something like what you're doing, I've gotten into trouble. Now I always just declare empty container ViewGroups in XML and do fragment transactions on them in the code.
You have two choices:
Use the coded fragment and change your listview.xml to this:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_place"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
or
Use the XML-declared fragment and change your onCreate() to this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview);
}
I have created a custom layout for ListFragment, using ArrayAdapter, but when the array is empty, no empty message is displayed. I get no errors on the console. My min SDK version is 15, there should be no need to use support libraries.
headline_list.xml (i.e. my custom layout file)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#id/android:list" />
<TextView android:id="#+id/my_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
HeadlineFragment.java
public class HeadlineFragment extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.headline_list, container, false);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
List<String> headlines = ...; // populate headlines list
setListAdapter(new ArrayAdapter<String>(getActivity(),
R.layout.headline_list, R.id.my_text, headlines));
}
}
You are getting suggestions here, you should do the tries.. Anyway this layout is working perfectly for me:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
ArrayAdapter adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, from);
setListAdapter(adapter);
return rootView;
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragmet"
android:layout_height="match_parent"
android:layout_width="match_parent">
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- Here is the view to show if the list is emtpy -->
<TextView
android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="No Results" />
</RelativeLayout>
I had simply forgot to set the text!
After setting it, my TextView is displayed correctly:
<TextView android:id="#id/android:empty"
android:textSize="16sp"
android:textStyle="bold"
android:text="#string/empty_text"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
with string resource in strings.xml file:
<string name="empty_text">There are no data</string>
Unfortunately, the TextView is also displayed in each row of the list, but this is another question.
It may be related to the linear layout and the fact you didn't specified weight attribute to each of the items, so one may overlay another. Check your layout params and this:
Showing empty view when ListView is empty
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
This is the layout of my navigation drawer:
<?xml version="1.0" encoding="utf-8"?>
<!-- the root view is now a LinearLayout, all other Views are children of this -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#121314"
android:orientation="vertical">
<!-- a separate section to go above the list -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp">
<!-- your image, you can set it later (see NavDrawerFrag) -->
<ImageView
android:id="#+id/nav_image"
android:layout_width="150dp"
android:layout_height="150dp"
android:padding="15dp"
android:src="#android:drawable/ic_menu_myplaces"/>
<!-- a bit of test or a title to go with it
<TextView
android:id="#+id/nav_text"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="Default text"/>-->
</LinearLayout>
<!-- some divider thing
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:padding="20dp"
android:background="#000000"/>-->
<!-- your ListView is now a child View -->
<ListView
android:id="#+id/nav_listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:listSelector="#drawable/colors"/>
</LinearLayout>
I want a custom font in the ListView, but I've been busting my head for two days straight on this. I just can't seem to get it working.
This is the part where the Navigation Drawer is created:
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState)
{
// need site names for list
siteNames = getActivity().getResources().getStringArray(R.array.site_names);
Log.d(TAG, "number of sites loaded: " + siteNames.length);
// inflate the parent view (the entire layout)
View view = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
// now grab the separate child views from inside it
mDrawerListView = (ListView) view.findViewById(R.id.nav_listView);
mDrawerImage = (ImageView) view.findViewById(R.id.nav_image);
//mDrawerText = (TextView) view.findViewById(R.id.nav_text);
// configure the Views
mDrawerImage.setImageResource(R.drawable.orange);
mDrawerListView.setOnItemClickListener(this);
mDrawerListView.setAdapter(new ArrayAdapter<String>(getActionBar().getThemedContext(),
android.R.layout.simple_list_item_1, android.R.id.text1, siteNames));
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
// and return the inflated view up the stack
return view;
}
Instead of using the android.R.id.text1 as your textview resource, you should create your own textview xml layout. You could do something like this
<?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:id= "#+id/listView >
<TextView
android:id="#+id/listItem"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TextView
</LinearLayout>
The following is the custom adapter you will need so you can set your custom styles to your individual items.
public class listAdapter extends BaseAdapter {
String[] siteNames;
Activity a;
public listAdapter(Activity a, String[] siteNames) {
this.a = a;
this.siteNames = siteNames;
}
public int getCount() {
return siteNames.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi = convertView;
vi = a.getLayoutInflater().inflate(R.layout.listView, null);
Typeface tf = Typeface.createFromAsset(a.getAssets(), "fonts/Raleway-Thin.otf");
TextView tv = (TextView) vi.findViewById(R.id.listItem);
tv.setTypeface(tf);
//whatever other changes you want to make to your list items.
return vi;
}
}
You then create a new adapter from this "listAdapter" class, or whatever you would like to name it. Then you can set your listview with this adapter and you should be good to go.
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!