无法在自定义适配器中获取onClickButton以正确响应?

时间:2015-04-25 10:14:52

标签: android listview adapter

我试图在列表视图中单击按钮时更改按钮的文本,我尝试通过自定义适配器执行此操作。使用日志调用onclick只是文本似乎没有改变:

这是我的适配器代码:

public class UserViewerAdapter extends BaseAdapter {
    public List<DatabaseUser> _list;
    public List<UserResponse> _listForSearch;
    private final Activity mContext;
    private ConfirmManager confirmManager;
    private int query;
    private Button isFriend;
    // database helper
    private DatabaseHelper db;

    private static LayoutInflater inflater = null;

    public UserViewerAdapter(Activity context, List<DatabaseUser> list) {
        mContext = context;
        _list = list;
        //establishing db
        db = new DatabaseHelper(mContext);
        confirmManager = new ConfirmManager();
        query = 0;

    }

    public UserViewerAdapter( List<UserResponse> list, Activity context) {
        mContext = context;
        _listForSearch = list;
        query = 1;
        //establishing db
        db = new DatabaseHelper(mContext);
        confirmManager = new ConfirmManager();

    }

    @Override
    public int getCount() {
        if(query == 0) {
            return _list.size();
        }
        return _listForSearch.size();
    }

    @Override
    public Object getItem(int position) {

        if(query == 0) {
            return _list.get(position);
        }
        return _listForSearch.get(position);
    }

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


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {


        View v = convertView;
        if (v == null) {
            LayoutInflater inflater = mContext.getLayoutInflater();
            v = inflater.inflate(R.layout.users_layout, null);


        }


        ImageView userImage = (ImageView) v.findViewById(R.id.userImage);
        TextView text = (TextView) v.findViewById(R.id.label);
         isFriend = (Button) v.findViewById(R.id.btnFriend);

        String isFriendText;


        //coming from search
        if(query == 1) {
            if (_listForSearch != null && _listForSearch.size() > 0) {
                text.setText(_listForSearch.get(position).getName());
            }

            Picasso.with(mContext).setLoggingEnabled(true);

//        String pictureToAdd = Constants.USER_IMAGES + _listForSearch.get(position).getPicId();
//        String photo = _listForSearch.get(position).get_picture();
//        Log.d(Constants.DEBUG, "THE photo IS " + photo);
//        Log.d(Constants.DEBUG, "THE constant IS " + Constants.USER_IMAGES);

//        if (photo.equals("default.jpg")) {
            Picasso.with(mContext).load(R.drawable.default_profile_image).resize(50, 50).into(userImage);

            isFriendText = "Add Friend";
            if(_listForSearch.get(position).isFriend()) {

                isFriendText = "Remove Friend";
            }
            isFriend.setText(isFriendText);


            final String finalIsFriendText = isFriendText;
            isFriend.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {

                    //Remove friend
                    callConfirmAddOrRemove(_listForSearch.get(position), finalIsFriendText);

                    Log.d(Constants.DEBUG, "clicked friend button " + finalIsFriendText);

                }
            });
        }



        return v;
    }

    private void changeText(String finalIsFriendText) {
        String newTextToFill = "";
        if(finalIsFriendText.equals("Remove Friend")) {
            newTextToFill = "Add Friend";
        }
        if(finalIsFriendText.equals("Add Friend")) {
            newTextToFill = "Remove Friend";
        }

        Log.d(Constants.DEBUG, "changing text of friend button " + newTextToFill);

        isFriend.setText(newTextToFill);
        notifyDataSetChanged();

    }
    private void callConfirmAddOrRemove(UserResponse userResponse, String finalIsFriendText) {

        boolean dlg = confirmManager.Confirm(mContext, mContext.getString(R.string.remove_friend), mContext.getString(R.string.details_confirmation)
                        + "\n" + mContext.getString(R.string.details_info),
                mContext.getString(R.string.submit), mContext.getString(R.string.cancel), addOrRemove(userResponse, finalIsFriendText),
                cancelPost());

    }

    private Runnable addOrRemove(final UserResponse userResponse, final String finalIsFriendText) {
        return new Runnable() {
            public void run() {
                sendToDb(userResponse, finalIsFriendText);

            }

        };
    }

    private void sendToDb(UserResponse userResponse, String finalIsFriendText) {


        Log.d(Constants.DEBUG, "sending to db friend change");
        String uid, name, picid;
        int points, totalshifts, totalhours, isguarding, isfriend;
            uid = userResponse.getUserId();
            name = userResponse.getName();
            picid = userResponse.getPictureId();
            points = userResponse.getTotalPoints();
            totalshifts = userResponse.getTotalShifts();
            totalhours = userResponse.getTotalHours();
            isguarding = 0;
            if(userResponse.isCheckedIn()) {
                isguarding = 1;
            }

            //have to do the opposite since trying to add or remove 3 means newly added friend, 2 means newly removed friend
            isfriend = 3;

            if(userResponse.isFriend()) {
                isfriend = 2;
            }


        DatabaseUser addOrRemoveUser = new DatabaseUser(uid, name, picid, points, totalshifts,totalhours, isguarding, isfriend);

        db.updateFriend(addOrRemoveUser);
        changeText(finalIsFriendText);
        notifyDataSetChanged();
    }



    private Runnable cancelPost() {
        return new Runnable() {
            public void run() {
                Log.d(Constants.DEBUG, "Canceled posting item");
            }
        };
    }




}

这是xml(我在itemclick工作时将list focus设置为false for listview):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dip" >
    <!--  ListRow Left side Thumbnail image -->
    <LinearLayout android:id="@+id/thumbnail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="3dip"
        android:layout_alignParentLeft="true"
        android:layout_marginRight="5dip">

        <ImageView
            android:id="@+id/userImage"
            android:layout_width="50dip"
            android:layout_height="50dip"
            android:focusable="false"
            android:focusableInTouchMode="false"/>

    </LinearLayout>
    <!-- Name-->
    <TextView
        android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/thumbnail"
        android:layout_centerInParent="true"
        android:layout_marginLeft="25dip"
        android:textColor="#040404"
        android:typeface="sans"
        android:textSize="15dip"
        android:textStyle="bold"
        android:text="DEFAULT NAME"
        android:focusable="false"
        android:focusableInTouchMode="false"/>


    <!-- Friend button -->
   <Button android:id="@+id/btnFriend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/friends"
        android:layout_marginRight="5dp"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:textSize="15dip"
       android:focusable="false"
       android:focusableInTouchMode="false"/>



</RelativeLayout>

3 个答案:

答案 0 :(得分:1)

您正尝试在单独的线程中更改文本,但是,只有 UI主线程可以更改TextViews和Buttons等视图。

要解决此问题,您可以使用runOnUiThread

runOnUiThread(new Runnable() {
    public void run() {
        // Update Button Text
    }
});

所以,在sendToDB中,更改

changeText(finalIsFriendText);

runOnUiThread(new Runnable() {
    public void run() {
        changeText(finalIsFriendText);
    }
});

runOnUIThread是来自java.lang.Runnable的方法,可以在Docs

中看到
  

在UI线程上运行指定的操作。如果当前线程是   UI线程,然后立即执行操作。如果是当前的   线程不是UI线程,操作被发布到事件队列   UI线程。

因此,它是一个函数,它将您输入的Runnable作为参数,并在UI线程中运行它,从而可以更改任何其他线程中的UI元素。

答案 1 :(得分:1)

getView的点击监听器中,方法为:

callConfirmAddOrRemove(_listForSearch.get(position), finalIsFriendText);

您无法正确position,因此您必须使用按钮position定义最终position或绑定isFriend标记。

[<强>更新

isFriend.setTag(position); //this is inside getView

然后在你的听众中:

int position = (int)v.getTag(); //this position will be correct one

希望这有帮助!

答案 2 :(得分:0)

我认为问题是isFriend用于更新文本,使用另一个来执行此操作。

还要注意 UI主线程问题。

private Button btnToUpdate;

@Override
public void onClick(View v) {
    btnToUpdate = v; //save which button to update
    //Remove friend
    callConfirmAddOrRemove(_listForSearch.get(position), finalIsFriendText);

    Log.d(Constants.DEBUG, "clicked friend button " + finalIsFriendText);

}

private void changeText(String finalIsFriendText) {
    String newTextToFill = "";
    if(finalIsFriendText.equals("Remove Friend")) {
        newTextToFill = "Add Friend";
    }
    if(finalIsFriendText.equals("Add Friend")) {
        newTextToFill = "Remove Friend";
    }

    Log.d(Constants.DEBUG, "changing text of friend button " + newTextToFill);

    btnToUpdate.setText(newTextToFill); //use btnToUpdate to update text
    notifyDataSetChanged();

}