I am attempting to create shared element transition between two Activities. This appears to work find between two layouts, each containing a single ImageView. However, I am having issues getting this transition to work with a ListView.
The issue is when the user taps on the first row, the transition will work as expected. However, when the second row is tapped, the origin of the transition appears to be the image of the first row as well!
I have created a simple list view with a custom row layout:
row_detailed.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Daft Punk"
android:id="#+id/primary_textview"
android:layout_gravity="center_horizontal"
android:layout_weight="0.07"
android:layout_alignTop="#+id/primary_imageview"
android:layout_toRightOf="#+id/primary_imageview" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Random Access Memories"
android:id="#+id/textView4"
android:layout_gravity="center_horizontal"
android:layout_weight="0.07"
android:layout_alignBottom="#+id/primary_imageview"
android:layout_toRightOf="#+id/primary_imageview" />
<ImageView
android:layout_width="84dp"
android:layout_height="84dp"
android:id="#+id/primary_imageview"
android:src="#drawable/ram"
android:layout_weight="0.07" />
</RelativeLayout>
The layout for the secondary Activity, activity_transition_secondary.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="legiocode.com.tapstrprototype.activity.TransitionSecondaryActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/secondary_imageview"
android:src="#drawable/ram"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
The Primary Activity, TransitionPrimaryActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transition_primary);
ListView listView = (ListView)findViewById(R.id.listView2);
ArrayAdapter<String> adapter = new ArrayAdapter(this,
R.layout.row_detailed,
R.id.primary_textview,
items);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String transitionName = getString(R.string.transition_image) + String.format("_%d", i);
ImageView imageView = (ImageView)findViewById(R.id.primary_imageview);
imageView.setTransitionName(transitionName);
Intent intent = new Intent(TransitionPrimaryActivity.this, TransitionSecondaryActivity.class);
intent.putExtra(TransitionSecondaryActivity.TRANSITION_NAME, transitionName);
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation(TransitionPrimaryActivity.this,
imageView, // The view which starts the transition
transitionName // The transitionName of the view we’re transitioning to
);
ActivityCompat.startActivity(TransitionPrimaryActivity.this, intent, options.toBundle());
}
});
}
The Secondary Activity, TransitionSecondaryActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transition_secondary);
String transitionName = getIntent().getStringExtra(TRANSITION_NAME);
ImageView imageView = (ImageView)findViewById(R.id.secondary_imageview);
imageView.setTransitionName(transitionName);
}
I have tried to implement the transition names dynamically, but that doesn't seem to make much of a difference. Am I setting up the transition correctly?
You have to access your actually clicked View (in this case parameter view) in
onItemClick(AdapterView<?> adapterView, View view, int i, long l)
With
ImageView imageView = (ImageView)findViewById(R.id.primary_imageview);
you always access the first element in the list.
PS: Put the transition names inside the xml. Makes it much more easy to read.
Related
I want to update the style of the selected item inside a ViewPager.
How can I do this?
This is the UI design. As you can see, the "November" tab is selected, so the corresponding bar is highlighted in yellow.
The way I've implemented this is a ViewPager with a custom item (white, not highlighted):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="142dp"
android:layout_height="275dp"
android:layout_margin="0dp"
app:cardElevation="0dp"
app:cardBackgroundColor="#android:color/transparent">
<TextView
android:id="#+id/monthly_spend_month"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/December"
android:textColor="#color/aluminum"
android:textSize="20sp"
android:textStyle="normal"
android:layout_marginStart="22dp"
android:layout_marginTop="34dp"/>
<RelativeLayout
android:id="#+id/monthly_spend_card"
android:layout_marginTop="120dp"
android:layout_marginStart="22dp"
android:layout_width="120dp"
android:layout_height="155dp"
android:background="#drawable/monthlyspend_card_bg_inactive">
<TextView
android:id="#+id/monthly_spend_text"
android:textColor="#color/almost"
android:layout_marginTop="50dp"
android:layout_marginStart="22dp"
android:text="Total
spent"
android:textSize="#dimen/balanceDescTextSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/monthly_spend_amount"
android:textColor="#color/almost"
android:layout_marginTop="10dp"
android:layout_marginStart="22dp"
android:layout_below="#id/monthly_spend_text"
android:text="$ 254.98"
android:textSize="#dimen/balanceDescTextSize"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
I plan on doing the highlighting programmatically.
Here's some adapter code:
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.monthlyspend_item, container, false);
TextView monthlySpendMonth, monthlySpendAmount;
monthlySpendCard = view.findViewById(R.id.monthly_spend_card);
monthlySpendMonth = view.findViewById(R.id.monthly_spend_month);
monthlySpendAmount = view.findViewById(R.id.monthly_spend_amount);
monthlySpendMonth.setText(monthlySpendings.get(position).getMonth());
monthlySpendAmount.setText(monthlySpendings.get(position).getAmountSpent());
container.addView(view, 0);
return view;
}
Any help would be appreciated!
I thing you are missing click listener :
view.setOnClickListener(new OnClickListener(){
public void onClick(View v){
// do you stuff here
}
});
((ViewPager)container).addView(view, 0)
Also inside instantiateItem() make int position as final.
you should change your model (in your case "monthlyspendings") at the selected item position.
then notify the adapter
adapter.notifyDataSetChanged()
and finally, custom selected view according to the model. for exapmle :
if(monthlySpendings.get(position).isSelected) monthlySpendCard.setBackgroundColor(Color.parseColor("#fcd14b"));
activity_main.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:longClickable="false"
android:orientation="vertical"
android:weightSum="16"
android:animateLayoutChanges="true">
<LinearLayout
android:id="#+id/ly_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="5dp"
android:background="#drawable/item_background"
android:text="Indonesia"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="5dp"
android:background="#drawable/item_background"
android:text="English"/>
</LinearLayout>
<LinearLayout
android:id="#+id/ly_ll2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="5dp"
android:background="#drawable/item_background"
android:text="Spain"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="5dp"
android:background="#drawable/item_background"
android:text="Brazil"/>
</LinearLayout>
</LinearLayout>
MainActivity.java:
public class MainActivity extends Activity {
LinearLayout llLayout;
LinearLayout llLayout2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
llLayout = (LinearLayout) findViewById(R.id.ly_ll);
llLayout2 = (LinearLayout) findViewById(R.id.ly_ll2);
for(int i=0;i<llLayout2.getChildCount();i++){
View views = llLayout2.getChildAt(i);
views.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addedViewTarget(v);
}
});
}
}
public void addedViewTarget(View view){
llLayout2.removeView(view);
llLayout.addView(view);
}
}
I have a case where the case is to move the view from viewgroup to another viewgroup. The problem is when I delete a code llLayout.addView(view); it's no problem and the view is successfully erased, but when I want to add a view to llLayout always an error like this "The specified child already has a parent. You must call removeView() on the child's parent first". So, I want to move the view in llLayout2 to llLayout when clicked, are you guys the best solution for this case?
oO yes you are right i tried your code and dose not works
i tried few things and i came up with this weird solution :|
public void addedViewTarget(final View view) {
ViewGroup vg = ((ViewGroup) view.getParent());
vg.removeView(view);
view.postDelayed(new Runnable() {
#Override
public void run() {
llLayout.addView(view);
}
},1000 );
}
i don't know why your code is not working and i dont know why this code is working but I have this hypothesis when you are saying remove View its takes some Time maybe in other thread and when your trying add the view to other ViewGroup instantly it raise error because removing task not complete yet
Try this
if(view.getParent()!=null)
((ViewGroup)view.getParent()).removeView(view);
llLayout.addView(view);
I want to display all items of an ArrayList<String> on a ListView. I use an ArrayAdapter<String> for this. The problem is that only the first item ('foo' in my example) of the ArrayList is shown. Can someone tell me why? Am I missing something?
I've made an minimal example using the generated code (Tabbed Action Bar Spinner Activity) from Android Studio 2.
My FooActivity:
public class FooActivity extends AppCompatActivity {
...
public static class PlaceholderFragment extends Fragment {
private ListView fooListView;
private ArrayAdapter<String> mAdapter;
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_foo, container, false);
fooListView = (ListView) rootView.findViewById(R.id.foo_list);
updateList();
return rootView;
}
private void updateList() {
ArrayList<String> strings = new ArrayList<>();
strings.add("foo");
strings.add("bar");
if (mAdapter == null) {
mAdapter = new ArrayAdapter<>(getContext(),
R.layout.item_foo,
R.id.foo_string,
strings);
fooListView.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(strings);
mAdapter.notifyDataSetChanged();
}
}
}
My fragment_foo.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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.foo.activities.FooActivity$PlaceholderFragment">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/foo_list"
android:layout_below="#+id/total_activities"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="10dp"
android:layout_alignParentBottom="true" />
</RelativeLayout>
And the item_foo.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">
<TextView
android:id="#+id/foo_string"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="some_string"
android:textSize="20sp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</LinearLayout>
If it helps I can post the generated activity_foo.xml (I didn't made any changes there) and the complete FooActivity class too.
The Problem actually was my activity_foo.xml which had a NestedScrollView. I've added android:fillViewport="true" and now it shows every item.
My NestedScrollView now looks like this:
<android.support.v4.widget.NestedScrollView
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:fillViewport="true"/>
On any ListView, if you use android:layout_height="wrap_content", you're only going to see one item. Try android:layout_height="match_parent". If the ListView only takes up part of the layout, you'll need a LinearLayout with weights or a RelativeLayout with constraints. But wrap_content won't work for a height on a ListView, ever.
Your Listview look something like this
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/foo_list"
android:layout_marginTop="10dp"/>
I have removed from your list view android:layout_below="#+id/total_activities"
and
android:layout_alignParentBottom="true"
For others: It's okay to nest a ListView inside another layout, and it's also fine to use android:layout_height="wrap_content" on Layouts surrounding the ListView. (So long as the outer-most Layout allows for match_parent)
What is not fine, however, is when the TextView being used to populate the ListView is defined with layout_height="match_parent". It will cover up all of the subsequent rows after the first.
Bad:
<TextView
android:id="#+id/infoRow_textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
Good:
<TextView
android:id="#+id/infoRow_textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
Problem
I'm trying to create a ListView with selectable items. I want to be able to click on an item in the ListView and have the item change color in the list, and then go on and do something else with the data from the row.
I'm using a SimpleAdapter.
How do I make it so that when I tap on a row, it turns a different color, and then when I tap on a different row, the new row is selected and changed to a new color, and the old row changes back to normal?
Code
Here is my code so far. The DBTools class is has all of the data that I want to be displayed in my ListView organized and taken care of. The getAllReceivers() method returns an ArrayList of HashMap<String, String>s that have all of my data.
MainActivity.java:
public class MainActivity extends ListActivity {
DBTools dbTools = new DBTools(this);
ArrayList<HashMap<String, String>> receiverList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().hide();
setContentView(R.layout.activity_main);
receiverList = dbTools.getAllReceivers();
dbTools.close();
ListView listView = getListView();
if(receiverList.size() != 0) {
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,receiverList, R.layout.receiver_entry, new String[] {"receiverId","receiverName", "fullPath"}, new int[] {R.id.receiverId, R.id.receiverName, R.id.fullPath});
setListAdapter(adapter);
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/black" >
<TextView
android:id="#+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="My List" />
</TableRow>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/black"
android:id="#android:id/list" />
</TableLayout>
receiver_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/tableRow" >
<TextView
android:id="#+id/receiverId"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<TextView
android:id="#+id/receiverName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Robotronics" />
<TextView
android:id="#+id/fullPath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123.45.678.910:8088/robtrox/find" />
</TableRow>
Solution
The solution to this problem is very simple. We need to add an OnItemClickListener to our ListView to listen for clicks and respond accordingly.
So, in the onCreate() method, once you've made sure that you set of data isn't empty, you're going to want to Override the onItemClick() method to listen for the click and change the color. You're also going to want to keep track of which item you selected for the later steps, so add public int selectionId = -1; at the top of your class. Furthermore, you'll need to let the ListAdapter know that you changed something by calling ((SimpleAdapter) getListAdapter()).notifyDataSetChanged().
if(receiverList.size() != 0) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int index, long id) {
view.setBackgroundColor(Color.RED);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
selectionId = Integer.valueOf(receiverIdTextView.getText().toString());
((SimpleAdapter) getListAdapter()).notifyDataSetChanged();
}
});
SimpleAdapter adapter = getNewAdapter();
setListAdapter(adapter);
}
Great! Now we have a working system that will change the color of the row that you tap. But we're not done yet. We need to make sure that the previous selection changes back to the normal color.
For this, we are going to use override the SimpleAdapter's getView() method, which is called everytime the ListView goes to draw the items being displayed in it.
It only actually displays the items it needs to - the ones that you can see. It does not render the ones above or below your screen. So if you have 200 items in a ListView, only 5 or 6, depending on the size of your screen and the size of the items, are being rendered at a time.
To override the getView() method, go up to where you initialize the adapter and change the code to this:
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,receiverList, R.layout.receiver_entry, new String[] { "receiverId","receiverName", "fullPath"}, new int[] {R.id.receiverId, R.id.receiverName, R.id.fullPath}) {
#Override
public View getView (int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
if(receiverIdTextView.getText().toString().equals(String.valueOf(selectionId))) {
view.setBackgroundColor(Color.RED);
} else {
view.setBackgroundColor(Color.WHITE);
}
return view;
}
};
Every time one of the rows is drawn, since the getView() will get called, the ListView will check if the current view has the id of row you selected. If it doesn't, it'll change the background color to white. If it does, it'll change the background color to red.
And voila! That's it! Now you are setting the background color to red when you click on an item in the ListView.
Final Code
MainActivity.java:
public class MainActivity extends ListActivity {
DBTools dbTools = new DBTools(this);
ArrayList<HashMap<String, String>> receiverList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().hide();
setContentView(R.layout.activity_main);
receiverList = dbTools.getAllReceivers();
dbTools.close();
ListView listView = getListView();
if(receiverList.size() != 0) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int index, long id) {
view.setBackgroundColor(Color.RED);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
selectionId = Integer.valueOf(receiverIdTextView.getText().toString());
((SimpleAdapter) getListAdapter()).notifyDataSetChanged();
}
});
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,receiverList, R.layout.receiver_entry, new String[] { "receiverId","receiverName", "fullPath"}, new int[] {R.id.receiverId, R.id.receiverName, R.id.fullPath}) {
#Override
public View getView (int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
if(receiverIdTextView.getText().toString().equals(String.valueOf(selectionId))) {
view.setBackgroundColor(Color.RED);
} else {
view.setBackgroundColor(Color.WHITE);
}
return view;
}
};
setListAdapter(adapter);
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/black" >
<TextView
android:id="#+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="My List" />
</TableRow>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/black"
android:id="#android:id/list" />
</TableLayout>
receiver_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/tableRow" >
<TextView
android:id="#+id/receiverId"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<TextView
android:id="#+id/receiverName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Robotronics" />
<TextView
android:id="#+id/fullPath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123.45.678.910:8088/robtrox/find" />
</TableRow>
i'm trying to catch the click event for a list of Switches
ListView list = (ListView) findViewById(R.id.main_view);
ArrayAdapter<String> LTRadapter = new ArrayAdapter<String>(this, R.layout.list_main_view_item, R.id.switch1, values);
list.setAdapter(LTRadapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int pos, long id) {
Log.w("MiniTasker","w00t " + Integer.toString(pos));
}
});
i've added android:descendantFocusability="blocksDescendants" to the ListView but to no avail.
Here's activity_main.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: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"
android:orientation="vertical">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/main_view"
android:layout_gravity="left|center_vertical"/>
</LinearLayout>
and here's list_main_view_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:minHeight="?android:attr/listPreferredItemHeight"
android:focusable="false"
android:focusableInTouchMode="false">
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Switch"
android:id="#+id/switch1"
android:layout_gravity="center_horizontal|top"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true"
android:checked="true"
android:tag="0"/>
</RelativeLayout>
Ok you should add an id to your list view in your XML.
Then you can apply that ID to your ListView in your method:
ListView list = (ListView) findViewById(R.id.my_list_view);
Right now your list reference is pointing at your Linear layout (white space outside your actual ListView). That's why it detects clicks outside the ListView
I think if you set the clickable attribute to false for switch tag in XML like below, it would work.
android:clickable="false"
But, I don't see a point in adding a switch in a list view where switch wouldn't be reacting the way we need it to react to click events. If you replace switch with imageView or TextView it will work as those won't react to click events unless specified.
The only solution I found was to extend ArrayAdapter I used in the code and to override getView
public class MainListAdapter extends ArrayAdapter<String> {
...
Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = ((Activity) mycontext).getLayoutInflater();
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_main_view_item, null);
assert convertView!=null;
Switch s = (Switch)convertView.findViewById(R.id.switch1);
assert s!=null;
s.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.w("MiniTasker", "adapter w00t " + Integer.toString(view.getId()));
}
});
}
return super.getView(position, convertView, parent);
}
}
android:focusable="false"
android:focusableInTouchMode="false"
Add this in the XML inside the Switch element.