2

I'm completely new in Android programming and recently trying to make a ListFragment with an Adapter. The fragment initally intended to show a list which contains TextView, ImageButton, and ImageView. I successfully made the ImageButton works when it's clicked. But it doesn't do the same when I tried to click on the ListView. I have tried so many combinations about this as well. Like adding

android:focusable="false"

to every views, and

android:descendantFocusability="blocksDescendants"

to the root ListView layout but none of the solutions work for me. Is there any other solution for my case?

event_item_list.xml :

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="145dp"
    android:orientation="vertical"
    android:paddingTop="2.5dp"
    android:descendantFocusability="blocksDescendants">
    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="145dp"
        android:id="@+id/img_item"
        android:scaleType="centerCrop" />
    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="55dp"
        android:orientation="horizontal"
        android:layout_gravity="bottom"
        android:background="#AA000000">
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_gravity="center"
            android:gravity="left"
            android:layout_centerVertical="true"
            android:paddingLeft="10dp">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@android:color/white"
                android:id="@+id/txt_item_title"
                android:textSize="20sp"
                android:text="Title"
                android:textAllCaps="true"
                android:textStyle="bold"
                android:maxLines="1" />
            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textColor="@android:color/darker_gray"
                android:id="@+id/txt_item_date"
                android:textSize="15dp"
                android:text="Date"
                android:maxLines="1" />
        </LinearLayout>
        <ImageButton
            android:layout_width="55dp"
            android:layout_height="match_parent"
            android:id="@+id/imageButton"
            android:layout_gravity="center_vertical"
            android:src="@drawable/ic_right_arrow"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:tint="#ffffffff"
            android:scaleType="fitXY"
            android:drawSelectorOnTop="true"
            android:padding="15dp" />
    </RelativeLayout>
</FrameLayout>

agenda.java :

package com.permata.app.myapplication;


import android.app.ListFragment;
import android.content.Intent;
import android.os.Bundle;
import android.app.Fragment;
import android.support.design.widget.Snackbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ListView;

import java.util.ArrayList;


/**
 * A simple {@link Fragment} subclass.
 */
public class agenda extends ListFragment {

    public agenda() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_agenda, container, false);
        super.onCreateView(inflater, container, savedInstanceState);

        ArrayList<agenda_content> konten_agenda = getKonten();

        final ListView lv = (ListView)view.findViewById(android.R.id.list);
        lv.setAdapter(new agenda_adapter(this.getActivity(), konten_agenda));
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> a, View v, int position, long id) {
                Intent i = new Intent(getActivity(),agenda_details.class);
                startActivity(i);
            }
        }); //this doesn't work

        return view;
    }

    private ArrayList<agenda_content> getKonten() {
        ArrayList<agenda_content> results = new ArrayList<agenda_content>();

        agenda_content ct = new agenda_content();
        ct.setTitle("Agenda 1");
        ct.setDate("Date 1");
        ct.setImage(R.drawable.img_sample_1);
        results.add(ct);

        ct = new agenda_content();
        ct.setTitle("Agenda 2");
        ct.setDate("Date 2");
        ct.setImage(R.drawable.img_sample_2);
        results.add(ct);

        ct = new agenda_content();
        ct.setTitle("Agenda 3");
        ct.setDate("Date 3");
        ct.setImage(R.drawable.img_sample_3);
        results.add(ct);

        ct = new agenda_content();
        ct.setTitle("Agenda 4");
        ct.setDate("Date 4");
        ct.setImage(R.drawable.img_sample_1);
        results.add(ct);

        ct = new agenda_content();
        ct.setTitle("Agenda 5");
        ct.setDate("Date 5");
        ct.setImage(R.drawable.img_sample_2);
        results.add(ct);

        ct = new agenda_content();
        ct.setTitle("Agenda 6");
        ct.setDate("Date 6");
        ct.setImage(R.drawable.img_sample_3);
        results.add(ct);

        return results;
    }
}

agenda_adapter.java :

package com.permata.app.myapplication;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.media.Image;
import android.support.design.widget.Snackbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

public class agenda_adapter extends BaseAdapter {
    private static ArrayList<agenda_content> content_array;
    private LayoutInflater mInflater;
    public agenda_adapter(Context context, ArrayList<agenda_content> result) {
        content_array = result;
        mInflater = LayoutInflater.from(context);
    }


    @Override
    public int getCount() {
        return content_array.size();
    }

    @Override
    public Object getItem(int position) {
        return content_array.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView == null) {
            convertView = mInflater.inflate(R.layout.event_item_list, null);
            holder = new ViewHolder();
            holder.title = (TextView)convertView.findViewById(R.id.txt_item_title);
            holder.date = (TextView)convertView.findViewById(R.id.txt_item_date);
            holder.image = (ImageView)convertView.findViewById(R.id.img_item);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }

        holder.title.setText(content_array.get(position).getTitle());
        holder.date.setText(content_array.get(position).getDate());
        holder.image.setImageResource(content_array.get(position).getImage());

        ImageButton domore = (ImageButton)convertView.findViewById(R.id.imageButton);
        domore.setFocusable(false);
        domore.getBackground().setColorFilter(0xAAAC7805, PorterDuff.Mode.MULTIPLY);
        domore.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final Snackbar snackbar = Snackbar.make(v, "HEY!", Snackbar.LENGTH_LONG)
                        .setAction("Action", null);
                snackbar.show();
            }
        });
        return convertView;
    }
    static class ViewHolder {
        TextView title;
        TextView date;
        ImageView image;
    }
}

thanks.

EDIT : the fragment_agenda.xml contains :

<ListView
    android:layout_width="fill_parent"
    android:layout_height="fill_parrent"
    android:id="@id/android:list"
    android:drawSelectorOnTop="true"
</ListView>

SOLVED : changed agenda.java to extends Fragment instead of ListFragment set the Listview id in fragment_agenda to @+id/lv_item_agenda and set ListView lv to find R.id.lv_item_agenda instead of android.R.id.list.

But I still don't know why this kind of tricky fix works. I wonder if there's something related to android.R.id.list that makes me having this problem. Any idea?

rahadi
  • 156
  • 9

1 Answers1

0

Apparently that focusable trick only works for Buttons, and doesn't work for ImageButtons. See the comments in the answer here.

One thing that is used commonly in Android source code to get around this issue is a class called DontPressWithParentImageView. This class is used for the call button in the Android Contacts app.

/**
 * Special class to to allow the parent to be pressed without being pressed itself.
 * This way the line of a tab can be pressed, but the image itself is not.
 */
public class DontPressWithParentImageView extends ImageView {

    public DontPressWithParentImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void setPressed(boolean pressed) {
        // If the parent is pressed, do not set to pressed.
        if (pressed && ((View) getParent()).isPressed()) {
            return;
        }
        super.setPressed(pressed);
    }
}

Here is an example of how to use it in Java code:

    if (mCallButton == null) {
        mCallButton = new DontPressWithParentImageView(mContext, null);
        mCallButton.setId(id);
        mCallButton.setOnClickListener(mCallButtonClickListener);
        mCallButton.setBackgroundResource(R.drawable.call_background);
        mCallButton.setImageResource(android.R.drawable.sym_action_call);
        mCallButton.setPadding(mCallButtonPadding, 0, mCallButtonPadding, 0);
        mCallButton.setScaleType(ScaleType.CENTER);
    }

    mCallButton.setTag(tag);
    mCallButton.setVisibility(View.VISIBLE);

For you it would be something like this:

    DontPressWithParentImageView domore = (DontPressWithParentImageView)convertView.findViewById(R.id.imageButton);
    domore.setFocusable(false);
    //..............

Here is an example of how to use it in layout xml:

<com.permata.app.myapplication.DontPressWithParentImageView android:id="@+id/call_button"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:paddingLeft="14dip"
                android:paddingRight="14dip"
                android:layout_centerVertical="true"
                android:gravity="center"
                android:src="@android:drawable/sym_action_call"
                android:background="@drawable/call_background"
            />
Community
  • 1
  • 1
Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
  • thank you for the answer. btw, is there any possibility that the onitemclicklistener problem is caused by something else instead of ImageButton? since the problem exists even when I remove the ImageButton – rahadi Jan 23 '16 at 13:01