Hi guys I have a problem with the cool lib from nhaarman
I integrated successfully his lib with an activity extends ListActivity
public class MainActivity extends ListActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getListView().setDivider(null);
MyAdapter adapter = new MyAdapter();
//setListAdapter(adapter);
ScaleInAnimationAdapter swingRightInAnimationAdapter = new ScaleInAnimationAdapter(adapter);
swingRightInAnimationAdapter.setAbsListView(getListView());
setListAdapter(swingRightInAnimationAdapter);
for(int i = 0 ; i<10; i++)
{
adapter.add("task" + String.valueOf(i));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class MyAdapter extends ArrayAdapter<String>
{
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = (TextView) convertView;
if (tv == null) {
tv = new TextView(MainActivity.this);
}
tv.setText(getItem(position));
return tv;
}
}
}
This code above is working fine. The list_rows are fading in the screen.
But now I want to integrate this lib into a fragment with a listview within:
public class FragmentTask extends Fragment{
ListView listView;
MyAdapter adapter;
View view;
public FragmentTask() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(new Exception().getStackTrace()[0].getClassName(), new Exception().getStackTrace()[0].getMethodName());
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_tasks, container, false);
Button button = (Button) view.findViewById(R.id.btn_newTask);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
adapter.add("task");
//adapter.notifyDataSetChanged();
}
});
listView = (ListView) view.findViewById(R.id.taskListView);
listView.setDivider(null);
adapter = new MyAdapter(view.getContext());
ScaleInAnimationAdapter swingRightInAnimationAdapter = new ScaleInAnimationAdapter(adapter);
swingRightInAnimationAdapter.setAbsListView(listView);
listView.setAdapter(swingRightInAnimationAdapter);
return view;
}
private class MyAdapter extends ArrayAdapter<String>
{
Context context;
private MyAdapter(Context context) {
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.list_row,parent, false);
TextView title = (TextView) row.findViewById(R.id.textView);
title.setText(getItem(position));
return row;
}
}
Here is the xml fragment_tasks:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="#ffc7c7c7">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="New Task"
android:id="#+id/btn_newTask"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/taskListView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_above="#+id/btn_newTask"
/>
</RelativeLayout>
Now I have the effect that the rows only fade in if i "spam" new rows so that I have to scroll down. So the list items which were hided appear now with the fade-effect. But the other list items which have room in the listview without scrolling are not fading.
Do you understand me?
Please help me :-)
I had the same problem, but the problem is not the fragment. The height of list_view must be match_parent.
<ListView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/taskListView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_above="#+id/btn_newTask"
/>
description of the problem
Hope that helps
Related
I'm having trouble understanding how to use Intent to move list view elements. So I've made a separate project to practice this before actually figuring it out in my app. Basically, I want to have a "Favorites" activity that can be populated from something like a search results page. Instead of a search results page, I've just created a list view with some sample elements in them with a favorites button in each. I just need some guidance on how to go from there. Here is my code so far
MainActivity.java
public class MainActivity extends Activity {
private ArrayList<String> data = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView);
generateList();
listView.setAdapter(new MyListAdapter(this, R.layout.item_view, data));
}
private void generateList() {
for (int i = 0; i < 5; i++) {
data.add("row/item " + i);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class MyListAdapter extends ArrayAdapter<String> {
private int layout;
public MyListAdapter(Context context, int resource, List<String>
objects) {
super(context, resource, objects);
layout = resource;
}
#Override
public View getView(final int position, View convertView, ViewGroup
parent) {
ViewHolder minViewHolder = null;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layout, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.title = (TextView)
convertView.findViewById(R.id.list_item_text);
viewHolder.button = (Button)
convertView.findViewById(R.id.favorites_button);
viewHolder.button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
Toast.makeText(getContext(), "sent item " + position + "
to favorites tab", Toast.LENGTH_SHORT).show();
// data.remove(position);
MyListAdapter.this.notifyDataSetChanged();
}
});
convertView.setTag(viewHolder);
} else {
minViewHolder = (ViewHolder) convertView.getTag();
minViewHolder.title.setText(getItem(position));
}
return convertView;
}
}
public class ViewHolder{
TextView title;
Button button;
}
}
activity_main.xml
<RelativeLayout 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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_centerHorizontal="true" /> </RelativeLayout>
item_view.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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/list_item_text"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fav"
android:id="#+id/favorites_button"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
I haven't set up a second activity because I wanted ideas on how to create a list that is empty but can be populated by that favorites button press. Any help at all is greatly appreciated!
Update arraylist according to favourite and call
adapter.notifyDataChanged();
if listview is same,
otherwise for different listview call another listview with adapter and new filtered arraylist
I'm trying to populate a listview using a BaseAdapter, the problem I'm having is the textview which shows the data, refuses to actually draw the text.
I've called getText() on the textview, and it does show the correct information, however for some reason, it simply is not being rendered.
CustomAdapter:
public class CardListviewAdapter extends BaseAdapter {
private Context context;
private ArrayList<String> numbers;
private LayoutInflater layoutInflater;
public CardListviewAdapter(Context context, ArrayList<String> numbers) {
this.context = context;
this.numbers = numbers;
layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return numbers.size();
}
#Override
public Object getItem(int position) {
return numbers.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
if(convertView == null)
{
Log.i("Inflating","Inflating Layout...");
convertView = layoutInflater.inflate(R.layout.conversation,null);
}
holder.numbers = (TextView)convertView.findViewById(R.id.numbertitle);
Log.e("Number",holder.numbers.toString());
convertView.setTag(holder);
Log.i("Item:", "" + numbers.get(position));
holder.numbers.setText(numbers.get(position));
return convertView;
}
public final class ViewHolder
{
public TextView numbers;
}
}
MainActivity:
public class ConversationThreads extends AppCompatActivity {
private ListView listview;
CardListviewAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_conversation_threads);
this.listview = (ListView)findViewById(R.id.conversationListview);
populateConversations();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_conversation_threads, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void populateConversations()
{
Log.d("Populate", "Populating...");
//Array of Strings returned -- Target Data
ArrayList<String> numbers = TSMS.getConversationNumbers(getApplicationContext());
adapter = new CardListviewAdapter(getApplicationContext(),numbers);
listview.setAdapter(adapter);
}
}
Listview.xml Layout:
<RelativeLayout 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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:layout_gravity="center_horizontal"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".CThreads"
android:id="#+id/conversationThreadLayout">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/conversationListview" />
</RelativeLayout>
conversation.xml layout:
<?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="wrap_content"
android:background="#drawable/bg_card">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/numbertitle"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/lastmessage"
android:layout_below="#+id/numbertitle"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Edit: Fixed Listview ID error, however result is unchanged.
Edit2: Problem was white background listview, and white text.
Answer credit to #N1to, provided in comments.
You have in code:
this.listview = (ListView)findViewById(R.id.Listview);
Where in your XML your id is different:
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/conversationListview" />
Also, move it to your activity_conversation_threads.xml, it doesn't need separate layout.
Add to class `ConversationThreads:
private ArrayList<String> numbers;
private CardListviewAdapter adapter;
And then change your method to:
private void populateConversations()
{
Log.d("Populate", "Populating...");
//Array of Strings returned -- Target Data
numbers = TSMS.getConversationNumbers(getApplicationContext());
Log.d("ArrayList size", String.valueOf(numbers.size()); // check if it returns non zero
adapter = new CardListviewAdapter(getApplicationContext(),numbers);
listview.setAdapter(adapter);
}
Code for adapter
public class CardListViewAdapter extends BaseAdapter {
private Context context;
private ArrayList<String> numbers;
public CardListViewAdapter(Context context, ArrayList<String> numbers) {
this.context = context;
this.numbers = numbers;
}
#Override
public int getCount() {
return numbers.size();
}
#Override
public Object getItem(int position) {
return numbers.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
rowView = layoutInflater.inflate(R.layout.conversation, null);
ViewHolder viewHolder = new ViewHolder(rowView);
rowView.setTag(viewHolder);
}
final ViewHolder holder = (ViewHolder) rowView.getTag();
holder.numbers.setText(numbers.get(position));
return rowView;
}
public class ViewHolder {
private final TextView numbers;
public ViewHolder(View v) {
this.numbers = (TextView) v.findViewById(R.id.numbertitle);
}
}
}
I am trying to create a navigation draw which displays text and images. My project builds OK but when I open the navigation draw there is no text or images displayed. I have created a layout file for the image and text to be displayed on the navigation draw and I have set the adapter for the navigation draw as well as creating my own Adapter class.
I cant see what is wrong but something obviously is :) Any help is greatly appreciated.
Here are my files
navigation_draw_items.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">
<!-- THis file will contain the list of items in the navigation draw -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"></LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView"
android:layout_gravity="left" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/textView3"
android:layout_gravity="left"/>
</LinearLayout>
activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view which will be a fragment-->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- <LinearLayout
android:id="#+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
-->
<ListView android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#ffff"/>
<!-- </LinearLayout> -->
</android.support.v4.widget.DrawerLayout>
AdapterClass.java
public class AdapterClass extends BaseAdapter {
private Context context;
private NavigationItem[] navigationItems;
public AdapterClass(Context context, NavigationItem[] items)
{
this.context = context;
navigationItems = items;
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
if (convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.navigation_draw_items, parent,false);
}
else
{
row = convertView;
}
TextView tvTitle = (TextView) row.findViewById(R.id.textView3);
ImageView tvImage = (ImageView) row.findViewById(R.id.imageView);
tvTitle.setText(navigationItems[position].stringTitle);
tvImage.setImageResource(navigationItems[position].drawableIcon);
return row;
}
}
NavigationItem.java
public class NavigationItem {
public NavigationItem(int stringTitle, int drawableIcon)
{
this.stringTitle = stringTitle;
this.drawableIcon = drawableIcon;
}
public int stringTitle;
public int drawableIcon;
}
MainActivity.java
public class MainActivity extends Activity implements EditListFragment.OnFragmentInteractionListener {
//private String[] items;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
public void onFragmentInteraction(String id)
{
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
// To do
AdapterClass navigationMenuAdapter;
NavigationItem[] navigationMenuItems = {
new NavigationItem(R.string.cat, R.drawable.cat),
new NavigationItem(R.string.dog, R.drawable.dog),
new NavigationItem(R.string.fish, R.drawable.fish),
};
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
navigationMenuAdapter = new AdapterClass(this, navigationMenuItems);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerList.setAdapter(navigationMenuAdapter);
mDrawerList.setOnItemClickListener(new DrawItemClickListener());
// Old code
//mDrawerList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items));
//items = getResources().getStringArray(R.array.items_array);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class DrawItemClickListener implements ListView.OnItemClickListener
{
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
selectedItem(position);
}
}
private void selectedItem(int position)
{
switch (position)
{
case 0:
//Fragment addList = ItemList
//Fragment addList = new ItemList();
//Bundle args = new Bundle();
//args.putInt(ItemList.LIST_NUMBER, position);
//addList.setArguments(args);
Fragment addList = ItemList.newInstance();
FragmentManager addListFragmentManager = getFragmentManager();
addListFragmentManager.beginTransaction().replace(R.id.content_frame, addList).commit();
//mDrawerLayout.closeDrawer(mDrawerLayout);
break;
case 1:
Fragment editList = EditListFragment.newInstance();
FragmentManager editListFragmentManager = getFragmentManager();
editListFragmentManager.beginTransaction().replace(R.id.content_frame, editList).commit();
break;
case 2:
Fragment deleteList = EditListFragment.newInstance();
FragmentManager deleteListFragmentManager = getFragmentManager();
deleteListFragmentManager.beginTransaction().replace(R.id.content_frame, deleteList).commit();
break;
}
}
}
Good day, I'm trying to build a book shelf with a horizontal list inside a list view but when the app runs, the listview is blank.
What am i missing?
Here's my code (and some code from a tutorial which i was using as a guide)
ListBook.java
public class ListBooks extends ActionBarActivity {
ListView listView;
private VerticalAdapter verListAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_books);
listView = (ListView)findViewById(R.id.listbooks);
BookItem book1 = new BookItem("Fist of Fury");
BookItem book2 = new BookItem("Fist of the fists");
BookItem book3 = new BookItem("Enders game");
BookItem book4 = new BookItem("Lovers");
ArrayList<BookItem> arrayList = new ArrayList<BookItem>();
arrayList.add(book1);
arrayList.add(book2);
ArrayList<BookItem> list = new ArrayList<BookItem>();
list.add(book3);
list.add(book4);
ArrayList<ArrayList<BookItem>> group = new ArrayList<ArrayList<BookItem>>();
group.add(arrayList);
group.add(list);
verListAdapter = new VerticalAdapter(this, R.layout.activity_book_list, group);
listView.setAdapter(verListAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_list_books, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class VerticalAdapter extends ArrayAdapter<ArrayList<BookItem>> {
private int resource;
public VerticalAdapter(Context _context, int _ResourceId,
ArrayList<ArrayList<BookItem>> _items) {
super(_context, _ResourceId, _items);
this.resource = _ResourceId;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView;
if (convertView == null) {
rowView = LayoutInflater.from(getContext()).inflate(resource,
null);
} else {
rowView = convertView;
}
HorizontalListView hListView = (HorizontalListView) rowView
.findViewById(R.id.sublistview);
HorizontalAdapter horListAdapter = new HorizontalAdapter(
getContext(), R.layout.listitem, getItem(position));
hListView.setAdapter(horListAdapter);
return rowView;
}
}
private class HorizontalAdapter extends ArrayAdapter<BookItem> {
private int resource;
public HorizontalAdapter(Context _context, int _textViewResourceId,
ArrayList<BookItem> _items) {
super(_context, _textViewResourceId, _items);
this.resource = _textViewResourceId;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View retval = LayoutInflater.from(getContext()).inflate(
this.resource, null);
TextView topText = (TextView) retval.findViewById(R.id.title);
topText.setText(getItem(position).getTitle());
return retval;
}
}
}
Layout files
Listitem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#fff">
<ImageView
android:id="#+id/image"
android:layout_width="150dip"
android:layout_height="150dip"
android:scaleType="centerCrop"
android:src="#drawable/wood"
/>
<TextView
android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:gravity="center_horizontal"
/>
</LinearLayout>
activity_book_list.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:context="com.azed">
<com.HorizontalListView
android:id="#+id/sublistview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ddd"/>
</LinearLayout>
activity_list_books.xml
<LinearLayout 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:orientation="vertical"
tools:context="com.azed">
<ListView
android:id="#+id/listbooks"
android:layout_width="match_parent"
android:layout_height="match_parent"
></ListView>
</LinearLayout>
I have a Fragment which consists of a Button overlaid on a FrameLayout. A second ListView Fragment is inserted into the FrameLayout. The ListView scrolls correctly except if the touch event starts on top of the Button. The Button's onClick listener seems to intercept the scroll of the beneath ListView. How can I have the Button process click events, but not scroll events.
I have a basic solution working using a GestureDetector on the Button and passing the onScroll event to the ListView's smoothScrollBy function. This doesn't work easily for fling events though.
This question seems similar albeit the reverse situation. I don't think the accepted answer helps me.
Example:
main_fragment.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/sub_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="#+id/button"
android:layout_width="80dp"
android:layout_height="70dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="#999"
android:text="Button" />
</RelativeLayout>
Inflated by MainFragment:
public class MainFragment extends Fragment {
private static final String TAG = MainFragment.class.getSimpleName();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main_fragment, container, false);
Button button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "click");
}
});
FragmentTransaction fragmentTransaction = getActivity()
.getSupportFragmentManager().beginTransaction();
ListFragment f = new ListFragment();
fragmentTransaction.replace(R.id.sub_content, f);
fragmentTransaction.commit();
return view;
}
}
The Button has an onClickListener and a second fragment is inflated in place of the FrameLayout:
fragment_item_list.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Inflated by ListFragment:
public class ListFragment extends Fragment {
private static final String TAG = ListFragment.class.getSimpleName();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_item_list,
container, false);
ListView listView = (ListView) view.findViewById(R.id.list);
List<String> list = new ArrayList<String>();
for (int i=0; i<30; i++) {
list.add("Item: " + i);
}
MyAdapter adapter = new MyAdapter(getActivity(), list);
listView.setAdapter(adapter);
return view;
}
private class MyAdapter extends BaseAdapter {
private List<String> items;
private Context context;
public MyAdapter(Context context, List<String> items) {
this.items = items;
this.context = context;
}
#Override
public int getCount() {
return items.size();
}
#Override
public String getItem(int i) {
return items.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View convertView, ViewGroup parent) {
if (convertView==null) {
convertView = LayoutInflater.from(context).inflate(
R.layout.list_item, parent, false);
}
TextView textView = (TextView) convertView.findViewById(
R.id.list_item_text);
textView.setText(getItem(i));
return convertView;
}
}
}
The solution I found was to remove the onClickListener on the button and instead have a SimpleGestureDetector on the Button (see the docs).
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
#Override
public boolean onSingleTapUp(MotionEvent event) {
clickButton();
return true;
}
}
Where the button implements this in an onTouchListener:
mDetector = new GestureDetectorCompat(getActivity(), new MyGestureListener());
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return mDetector.onTouchEvent(motionEvent)
|| dispatchTouchEvent(motionEvent);
}
});
And the Button passes the touch event to the ListView via an interface (inside dispatchTouchEvent function) and calls:
listView.dispatchTouchEvent(motionEvent)
Useful reading includes this SO question and also this.