Home > Software engineering >  Android Studio - how to update Fragment's UI onButtonClick in a listview using BaseAdapter
Android Studio - how to update Fragment's UI onButtonClick in a listview using BaseAdapter

Time:02-20

The structure:

(1) Activity's FrameLayout -> (2) Fragment's ListView -> (3) Base Adapter

There are buttons such as like and reply in every row in the layout.

Whenever user hits the like button, I will have to change a TextView's text in the (1) Activity.

I couldn't find a solid answer thru searching.

So

I want communication between Adapter and Fragment.

Button click in BaseAdapter -> update UI in Activity(which contains fragment)

public class ForumDetailCommentFragment extends Fragment {

    private static final String ARG_COMMENTS = "ARG_COMMENTS";

    private ArrayList<Comment> mComments;

    public static ForumDetailCommentFragment newInstance(ArrayList<Comment> _comments) {

        Bundle args = new Bundle();
        args.putSerializable(ARG_COMMENTS, _comments);
        ForumDetailCommentFragment fragment = new ForumDetailCommentFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mComments = (ArrayList<Comment>) getArguments().getSerializable(ARG_COMMENTS);
        organizeComments();

        // adapter
        ListView lv_comments = view.findViewById(R.id.frag_forum_detail_comments_lv);
        lv_comments.setAdapter(new CommentAdapter(getActivity(), mComments));
        lv_comments.setDivider(null);
    }
}
public class CommentAdapter extends BaseAdapter {

    public static final String TAG = "ForumAdapter.TAG";

    // BASE ID
    private static final long BASE_ID = 0x1011;
    // reference to our owning screen(context)
    private Context mContext;
    // reference to our collection
    private Comment mComment = null;
    private ArrayList<Comment> mCollection;

    public CommentAdapter(Context _context, ArrayList<Comment> _collection) {
        this.mContext = _context;
        this.mCollection = _collection;
    }

    @Override
    public int getCount() {
        if(mCollection != null) return mCollection.size();
        return 0;
    }

    @Override
    public Object getItem(int position) {
        if(mCollection != null && position >= 0 && position < mCollection.size()){
            return mCollection.get(position);
        }
        return null;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder vh = null;
        mComment = (Comment) getItem(position);

        if(convertView == null){
            convertView = LayoutInflater.from(mContext).inflate(R.layout.lv_comment_layout, parent, false);
            vh = new ViewHolder(convertView);
            convertView.setTag(vh);
        }else{
            vh = (ViewHolder) convertView.getTag();
        }

        if( mComment != null){


//            vh.tv_filter_league.setFocusable(false);
//            vh.tv_filter_league.setFocusableInTouchMode(false);
//            vh.tv_filter_category.setFocusable(false);
//            vh.tv_filter_category.setFocusableInTouchMode(false);

            // TODO: loop through user's like list.
            // TODO: if contains, change the icon's color

            if(mComment.getLayer() == 0) vh.child_divider.setVisibility(View.GONE);
            else vh.child_divider.setVisibility(View.VISIBLE);


            vh.iv_emblem.setImageResource(mComment.getAuthorEmblem(mContext));
            vh.tv_author.setText(mComment.getAuthorUser().getUName());
            vh.tv_timestamp.setText(mComment.getDateTimestamp());
            vh.tv_desc.setText(mComment.getMentionId()   mComment.getDesc());

            vh.tv_like.setText(String.valueOf(mComment.getLike()));
            vh.tv_ycard.setText(String.valueOf(mComment.getYCards()));

            vh.btn_reply.setOnClickListener(onReplyTap);
            vh.btn_like.setOnClickListener(onLikeTap);
            vh.btn_ycard.setOnClickListener(onYCardTap);
        }
        return convertView;
    }

    View.OnClickListener onLikeTap = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //DBUtil.forum_update_like_on_comment(mContext, UPDATE_LIKE, mComment.getId());
        }
    };

    View.OnClickListener onYCardTap = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //DBUtil.forum_update_ycard_on_comment(mContext, UPDATE_LIKE, mComment.getId());
        }
    };

    View.OnClickListener onReplyTap = new View.OnClickListener() {
        @Override
        public void onClick(View view) {

        }
    };

    static class ViewHolder{

        // TODO:
        LinearLayout child_divider;
        ImageView iv_emblem;
        TextView tv_author, tv_timestamp, tv_desc, tv_like, tv_ycard, btn_reply;
        ImageButton btn_like, btn_ycard;


        public ViewHolder(View _layout){

            child_divider = _layout.findViewById(R.id.lv_base_forum_detail_divider_layer_2);

            iv_emblem = _layout.findViewById(R.id.lv_base_forum_detail_iv_emblem);

            tv_author = _layout.findViewById(R.id.lv_base_forum_detail_tv_uname);
            tv_desc = _layout.findViewById(R.id.lv_base_forum_detail_tv_desc);
            tv_timestamp = _layout.findViewById(R.id.lv_base_forum_detail_tv_timestamp);

            tv_like  = _layout.findViewById(R.id.lv_base_forum_detail_tv_like);
            tv_ycard = _layout.findViewById(R.id.lv_base_forum_detail_tv_ycard);

            btn_reply = _layout.findViewById(R.id.lv_base_forum_detail_btn_reply);
            btn_like = _layout.findViewById(R.id.lv_base_forum_detail_btn_like);
            btn_ycard = _layout.findViewById(R.id.lv_base_forum_detail_btn_ycard);
        }
    }
}

CodePudding user response:

Create an interface like:

public interface Callback {
    public void OnFavoriteClicked()
}

And make your fragment implements it. On your adapter, you should create a variable of this interface type (named callback, for example) and reference it from the fragment. From constructor

Adapter adapter = new Adapter(this@Fragment)

or some set method

adapter.setCallback(this)

Later, you can invoke the interface methods from your adapter like this:

callback.OnFavoriteClicked()

And the override method you must implement in the fragment should be called.

CodePudding user response:

In your view holder after you set your btn_like add an onClick event like this

btn_like.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // stuff you want
            }
        });

so now when a user clicks the button the code inside the onClick will run

now you want to get the text from the like counter, convert it to an integer and add 1. you can do it like so:

Integer.valueOf(tv_like.getText().toString()) 1;

and now all that's left is to set the text to the new value like so:

tv_like.setText((Integer.valueOf(tv_like.getText().toString()) 1)   "");

and now you put all those steps together and you get:

btn_like.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            tv_like.setText((Integer.valueOf(tv_like.getText().toString()) 1)   "");
        }
    });

Notice that this code hasn't been tested but it should work, let me know if you run into any problems.

I'm the guy from discord btw

  • Related