Visual feedback in customized ExpandableListView - android

I've adapted the standard ExpandableListView to use my own indicator image so I can remove it when a group has no children. I also made some changes that the text views in the group view have a separate OnClickListener to show some details about the group. Clicking on the indicator icon will expand/collapse the group as usual.
My question is how do I get the same visual feedback (shift in background color to blue and back) on clicking the text views of a group as I get when clicking the indicator icon or a child row?
My group layout is:
<?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="wrap_content"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="5dp" >
<TextView
android:id="#+id/news_group_timestamp"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/news_group_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingRight="5dp" />
<ImageView
android:id="#+id/news_group_exp_indicator"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="#drawable/news_group_expander" />
</LinearLayout>
The relevant portions of the adapter are listed below. The ViewHolder is a simple class to support various group types (section header or actual group item).
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
{
convertView = createGroupView(groupPosition);
fillGroupView(groupPosition, isExpanded, convertView);
return convertView;
}
protected class OnTextClickListener implements OnClickListener
{
protected int m_groupPosition;
public OnTextClickListener(int groupPosition)
{
m_groupPosition = groupPosition;
}
#Override
public void onClick(View v)
{
...
}
}
protected View createGroupView(int groupPosition)
{
View view = m_inflater.inflate(R.layout.news_group, null);
ViewHolder holder = new ViewHolder();
holder.groupExpIndicator = (ImageView) view.findViewById(R.id.news_group_exp_indicator);
// We set the OnClickListener for the timestamp and title views so we
// can use this to show the details of a group item. The expansion of
// the group is handled higher up where the indicator click is
// processed.
holder.groupTimestampView = (TextView) view.findViewById(R.id.news_group_timestamp);
holder.groupTimestampView.setOnClickListener(new OnTextClickListener(groupPosition));
holder.groupTitleView = (TextView) view.findViewById(R.id.news_group_title);
holder.groupTitleView.setOnClickListener(new OnTextClickListener(groupPosition));
view.setTag(holder);
return view;
}

Related

Android Expandable lIst View Group Expand Listener

I am using a expandable list view in my application with group expand and group collapse listeners.
But what happens is the right arrow click in the group row works absolutely perfect but when i tap on the row the group does not expand in a single clcik.
I have to tap it multiple times ,only then it expands.
here is the expandable list view group click listener code:
expandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
groupName = _groupNameList.get(i);
_header = _child.get(groupName);
if (_header.size() == 1 && _header.get(0).getServiceName().equals(groupName)) {
expandableListView.setGroupIndicator(null);
String id=_header.get(0).getServiceId();
Intent intent = new Intent(CategoryDetails1.this, ServiceSelectionOptionsListActivity.class);
SharedPreferences.Editor editor = CategoryDetails1.this.getSharedPreferences(AppConstants.VERIFICATION, CategoryDetails1.this.MODE_PRIVATE).edit();
editor.putString(AppConstants.SUBSERVICEID, id);
editor.commit();
startActivity(intent);
}
return false;
}
});
and here is the header row 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_gravity="center"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/tvGroupName"
android:layout_width="match_parent"
android:layout_marginLeft="20dp"
android:textSize="18dp"
android:layout_marginBottom="10dp"
android:textStyle="bold"
android:layout_marginRight="25dp"
android:layout_alignParentLeft="true"
android:inputType="textMultiLine"
android:textColor="#color/selecteditem"
android:layout_marginTop="10dp"
android:layout_height="wrap_content"
android:focusable="false" have tried this
android:layout_weight="1" />
<ImageView
android:id="#+id/groupindicator"
android:layout_width="30dp"
android:layout_marginBottom="10dp"
android:layout_height="30dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_alignParentRight="true"
android:src="#drawable/circle_plus" />
</RelativeLayout>
this is my getgroup view method
public View getGroupView(int groupPosition, boolean b, View view, ViewGroup viewGroup) {
if (view == null) {
view = mLayoutInflater.inflate(R.layout.expandable_list_header, null);
}
TextView tvGroupName = (TextView) view.findViewById(R.id.tvGroupName);
tvGroupName.setFocusable(false); //have tried it also
ImageView ivgroupicon = (ImageView) view.findViewById(R.id.groupindicator);
// ivgroupicon.setImageDrawable(mContext.getResources().getDrawable(R.drawable.servicescollapseicon));
tvGroupName.setText((String) getGroup(groupPosition));
int size = _child.get((String) getGroup(groupPosition)).size();
view.setPadding(0, 10, 0, 10);
if (size == 1 && _child.get((String) getGroup(groupPosition)).get(0).getServiceName().equals((String) getGroup(groupPosition))) {
ivgroupicon.setVisibility(View.GONE);
} else
ivgroupicon.setVisibility(View.VISIBLE);
if (b) {
ivgroupicon.setImageDrawable(mContext.getResources().getDrawable(R.drawable.servicesexpandicon));
} else {
ivgroupicon.setImageDrawable(mContext.getResources().getDrawable(R.drawable.servicescollapseicon));
}
return view;
}
Now what I want is i want smooth group expand and collapse listener in my activity.I have tried setFocusable to false in both my xml and adapter files but in Vain.
So guys please suggest me something asap.I am stuck in this from a very long time.
Add below property to your
TextView and ImageView
android:focusable="false"
And in Root Layout :RelativeLayout
android:descendantFocusability="blocksDescendants"

Android - OnItemClickListener only *sometimes* not working

I have a ListView in one of my activities that I have bound to an ArrayList using a custom ArrayAdapter. I have set an OnItemClickListener to the ListView which should call a method that starts another activity. However, I find that when I click on the ListView items, it only sometimes works. Sometimes it will start the activity as it should; other times it seems to detect the click (the ripple effect appears on the list item) but does nothing; other times it doesn't even appear to detect the click (the ripple effect doesn't appear).
I've tried all the usual suggestions that I've come across: blocking descendants on the parent view item, setting clickable and focusable to false on all the components of the item views, setting isEnabled to return true in the custom adapter, etc, but the behavior remains the same. Any help appreciated. Here is the relevant code:
Activity containing the ListView:
public class ViewCollectionActivity extends AppCompatActivity {
private final String className = this.getClass().getSimpleName();
private CollectionHandler collectionHandler;
private Context context;
private ArrayList<Game> displayedCollection;
private GameCollectionAdapter collectionAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_collection);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
context = this;
collectionHandler = CollectionHandler.getInstance(this);
TextView view = null;
if (collectionHandler.getDisplayedCollection().size() > 0) {
view = (TextView) findViewById(R.id.no_items_textview);
view.setVisibility(View.GONE);
}
String currentDate = collectionHandler.getDateLastSynchronised();
view = (TextView) findViewById(R.id.last_updated_textview);
view.setText("Last synchronised: " + currentDate + " Total games: " + String.valueOf(collectionHandler.getDisplayedCollection().size()));
collectionAdapter = collectionHandler.getCollectionAdapter();
ListView listView = (ListView) findViewById(R.id.collection_list_view);
listView.setAdapter(collectionAdapter);
AdapterView.OnItemClickListener collectionItemClickListener = new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
launchGameDetailsActivity(position);
}
};
listView.setOnItemClickListener(collectionItemClickListener);
}
public void launchGameDetailsActivity(int position){
Log.d(className,"Starting lauchGameDetailsActivity method");
collectionHandler.setSelectedGame(position);
Intent intent = new Intent(this,ViewGameDetailsActivity.class);
startActivity(intent);
Log.d(className, "Ending lauchGameDetailsActivity method");
}
The XML for the activity:
<?xml version="1.0" encoding="utf-8"?>
<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"
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.bleachedlizard.ludome.viewcollection.ViewCollectionActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Synchronise Collection"
android:onClick="synchroniseCollection"/>
<TextView
android:id="#+id/last_updated_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Last synchronised: "
android:textAlignment="center"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Display Collection"
android:visibility="gone"
android:onClick="displayCollection"/>
<ListView
android:id="#+id/collection_list_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
<TextView
android:id="#+id/no_items_textview"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="You have no items in your collection."
android:textAlignment="center"
android:textSize="20sp"/>
</LinearLayout>
The XML for the item views:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/collection_item_layout"
android:layout_width="match_parent"
android:layout_height="75dp"
android:orientation="horizontal"
android:clickable="false"
android:descendantFocusability="blocksDescendants"
android:focusable="false"
android:focusableInTouchMode="false">
<ImageView
android:id="#+id/collection_item_image"
android:layout_width="75dp"
android:layout_height="75dp"
android:src="#drawable/testimage"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
/>
<TextView
android:id="#+id/collection_item_name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:padding="16dp"
android:singleLine="false"
android:textColor="#android:color/darker_gray"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
android:textIsSelectable="false"/>
<TextView
android:id="#+id/collection_item_plays"
android:layout_width="100dp"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:padding="8dp"
android:textColor="#android:color/darker_gray"
android:text="Plays: 0"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
android:textIsSelectable="false"/>
</LinearLayout>
The code for the custom adapter:
public class GameCollectionAdapter extends ArrayAdapter<Game> {
private ArrayList<Game> collection;
public GameCollectionAdapter(Context context, int resource, ArrayList<Game> collection){
super(context, resource, collection);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout gameView = (LinearLayout) convertView;
LayoutInflater mInflater = LayoutInflater.from(getContext());
if (gameView == null) {
gameView = (LinearLayout) mInflater.inflate(R.layout.collection_item_view, null);
}
//Game game = collection.get(position);
Game game = super.getItem(position);
if (game != null) {
// This is how you obtain a reference to the TextViews.
// These TextViews are created in the XML files we defined.
TextView gameTitle = (TextView) gameView.findViewById(R.id.collection_item_name);
TextView numOfPlays = (TextView) gameView.findViewById(R.id.collection_item_plays);
ImageView thumbnail = (ImageView) gameView.findViewById(R.id.collection_item_image);
// check to see if each individual textview is null.
// if not, assign some text!
if (gameTitle != null){
gameTitle.setText(game.getTitle());
}
if (numOfPlays != null){
numOfPlays.setText("Plays: " + String.valueOf(game.getNumOfPlays()));
}
if (thumbnail != null){
thumbnail.setImageBitmap(game.getThumbnail());
}
}
// the view must be returned to our activity
return gameView;
}
#Override
public boolean isEnabled(int position) {
return true;
}
}
I discovered what was causing the problem: the way I had set up the array that backed the ListView meant that it was downloading and storing the Bitmaps for every element in the array all the time. Once I changed the implementation so that it only downloaded the images as the ListView required them, then that seemed to improve performance and the onClickListener started to work fine.
The implementation I used was the exact same one shown here:
http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
I think the issue is due to the position of the item selection whenever you click you have an list position which is passed to your method launchGameDetailActivity(int position) check with log or toast on item click what all the position you are getting do the needful.
Here is my code try this like this if it helps.
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(RecipeClass.this, "Position is" + position, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(RecipeClass.this, RecipeIngredients.class)
intent.putExtra("position", position);
startActivity(intent);
}
Check your arraylist value also whether they are not null.

Android ExpandableListView Parent with Button

I am trying to achieve something like this.
The Expandable List consists of the names of certain categories and when a parent is clicked, it shows the list of all the children in that category.
Now, suppose I want dynamically add a child to any category ?
How do I do that ?
Do I keep a button with every parent in the list clicking on which would add a new child under it ?
But looking around in different forums, I came to realize that it is not really easy to set a button click handler inside every parent. But if that is the only way, can anyone give me some sample code please ?
I found this thread but wasn't able to implement it in my code.
Android Row becomes Unclickable with Button
Adding a button to the group view shouldn't be that difficult.
I believe the below should work (although I don't have a project using an array backed ExpandableListView to test on).
I don't know your group row layout, so I'll make one up here for reference purposes.
group_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#android:id/text1"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center_vertical"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="#+id/addbutton"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Add"
android:textSize="12dp" />
</LinearLayout>
Then in your getGroupView method from your adapter:
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null) {
View convertView = View.inflate(getApplicationContext(), R.layout.group_layout, null);
Button addButton = (Button)convertView.findViewById(R.id.addButton);
addButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// your code to add to the child list
}
});
}
TextView textView = (TextView)convertView.findViewById(R.id.text1);
textView.setText(getGroup(groupPosition).toString());
return convertView;
}

Add a new item to a listview

I am not quite sure my question really has something to do with listview.There is an app named Gleeo Time Tracker ,and here has a screenview of it.When you press the symbol "+",a new item will be created,and you can delete one item by pressing the "-".More is that when I click the record button on the left of the item,the background will change.
My question is,what is it in the end,a listview? How can I achieve such thing?Thank you all!
What you want to do, is build a custom ListView.
This is done by providing a layout file, for example
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/transparent">
<ImageView android:id="#+id/Plus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent" />
<TextView android:id="#+id/Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent" />
</LinearLayout>
This layout is then applied to each row of your ListView by overriding its Adapter's getView() method, for example something like this:
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) MyActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
ImageView plus = (ImageView) v.findViewById(R.id.plus);
icon.setImageDrawable(BrowseActivity.this.getResources().getDrawable(R.drawable.plus));
TextView title = (TextView) v.findViewById (R.id.Browse_FileName);
// add a listener to your button and you're done
return v;
}
read about list view in developer docs and here is an example

How do I make this listview unselectable?

I want to make a listview unselectable and unclickable. I'm talking about the color change that occurs when I click on a list item. The code is given below. I'm a newbie in android so please be kind.
from : 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="fill_parent"
android:layout_height="fill_parent"
android:padding="8px">
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"/>
<TextView
android:id="#+id/data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16px"/>
</LinearLayout>
from : details.java
TestActionAdapter() {
super(TestDetails.this, R.layout.action_list_item, actions);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TestAction action = actions.get(position);
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.action_list_item, parent, false);
TextView label = (TextView) view.findViewById(R.id.label);
label.setText(action.getLabel());
TextView data = (TextView) view.findViewById(R.id.data);
data.setText(action.getData());
return view;
}
Check out the answer here:
How to disable list items...
Basically extend ArrayAdapter, and add these 2 functions:
#Override
public boolean areAllItemsEnabled() {
return false;
}
#Override
public boolean isEnabled(int position) {
return false;
}
If all you want is to prevent all rows highlighting on click just use ListView android:listSelector="#android:color/transparent"
When you return view from getView(..) Method, just put in view.setEnabled(false) before return view .

Categories

Resources