Search code examples
androidlistviewandroid-fragmentsadapter

Change ListView element in fragment


I would like to change, with a for loop in a fragment containing the cards (as shown in the image), each "test test" TextView so that it shows, for example, it's position in the ArrayAdapter. (so, Arnaud Dubois has "1" instead of "test test", John Snow has "2", and so on)...

I insist on the fact that this should be done in the fragment, and not in the arrayadapter class.

enter image description here

It seems I can't have access to the TextView from the fragment itself, only in the ArrayAdapter class. I have some code for the fragment here, but the elements don't change. The code that should update each element is in the "onConfirmedFriendsReceivedEvent".

public class FriendsFragment extends BaseFragment implements MaterialSearchBar.OnSearchActionListener {

ListView mFriendsList;
ConfirmedFriendsAdapter adapter;

private MaterialSearchBar searchBar;

View root_view;

public FriendsFragment(){

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState){
    View view = inflater.inflate(R.layout.fragment_friends, container, false);

    root_view = view;

    initUI(view);
    initEvent(view);

    return view;
}

public static FriendsFragment newInstance(@Nullable Bundle params){
    Bundle args = (params == null) ? new Bundle() : params;
    FriendsFragment fragment = new FriendsFragment();
    fragment.setArguments(args);
    return fragment;
}

@Override
void initUI(@Nullable final View view){
    mFriendsList = view.findViewById(R.id.friends_list);
    mFriendsList.setEmptyView(view.findViewById(R.id.empty));

    searchBar = (MaterialSearchBar) root_view.findViewById(R.id.friends_searchBar);
    searchBar.setHint("Search friends...");
    //enable searchbar callbacks
    searchBar.setOnSearchActionListener(this);

}

@Override
void initEvent(@Nullable final View view){
    FriendsDataManager.getConfirmedFriends();
}

@Override
public void onSearchStateChanged(boolean enabled) {
    String s = enabled ? "enabled" : "disabled";
    Toast.makeText(getContext(), "Search " + s, Toast.LENGTH_SHORT).show();
    //if (!searchBar.isSearchEnabled()) searchBar.enableSearch();
}

@Override
public void onSearchConfirmed(CharSequence text) {
    String search = text.toString();
    FriendsDataManager.getSearchedFriends(search);
}

@Override
public void onButtonClicked(int buttonCode) {
    switch (buttonCode) {
        case MaterialSearchBar.BUTTON_NAVIGATION:
            Toast.makeText(getContext(), "Machin truc", Toast.LENGTH_SHORT).show();
            break;
        case MaterialSearchBar.BUTTON_SPEECH:
            break;
        case MaterialSearchBar.BUTTON_BACK:
            FriendsDataManager.getConfirmedFriends();
            break;
    }
}

@Subscribe
public void onConfirmedFriendsReceived(ConfirmedFriendsEvent event){
    adapter = new ConfirmedFriendsAdapter(getActivity(), event.mConfirmedFriends);
    mFriendsList.setAdapter(adapter);
    adapter.setNotifyOnChange(true);
    for(int i=0; i<adapter.getCount(); i++){
        View v = getViewByPosition(i, mFriendsList);
        TextView msg = v.findViewById(R.id.friend_message);
        msg.setText(i);
    }
}

public View getViewByPosition(int pos, ListView listView) {
    final int firstListItemPosition = listView.getFirstVisiblePosition();
    final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;

    if (pos < firstListItemPosition || pos > lastListItemPosition ) {
        return listView.getAdapter().getView(pos, null, listView);
    } else {
        final int childIndex = pos - firstListItemPosition;
        return listView.getChildAt(childIndex);
    }
}

And here is the code for the ArrayAdapter class. Note that the "setMail" and "getMail" method is not accessible (so far) from the fragment. I would like to be able to access it from the fragment.

public class ConfirmedFriendsAdapter extends ArrayAdapter<ConfirmedFriend> {

private final List<ConfirmedFriend> mConfirmedFriends;
private final Context mContext;

private GeoDataClient geoDataClient;
private Place currentPlace;

String mail;

TextView friend_message;
TextView friend_position;

public ConfirmedFriendsAdapter(@NonNull final Context context, @NonNull final List<ConfirmedFriend> objects){
    super(context, R.layout.fragment_friends, objects);
    mConfirmedFriends = objects;
    mContext = context;
}

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

    final ConfirmedFriend confirmedFriend = mConfirmedFriends.get(position);
    if(convertView == null){
        convertView = LayoutInflater.from(mContext).inflate(R.layout.item_friends_feed, parent, false);
    }

    mail = confirmedFriend.getDest_user().getMail();

    TextView friend_name = convertView.findViewById(R.id.friend_name);
    TextView friend_asl = convertView.findViewById(R.id.friend_asl);
    friend_message = convertView.findViewById(R.id.friend_message);
    friend_position = convertView.findViewById(R.id.friend_position);


    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    Date date = new Date();
    String now = dateFormat.format(date);

    try {
        Date birthdate = new SimpleDateFormat("yyyy-MM-dd").parse(confirmedFriend.getDest_user().getBirthday());
        Date nowDate = new SimpleDateFormat("yyyy-MM-dd").parse(now);
        // validate inputs ...
        DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        int d1 = Integer.parseInt(formatter.format(birthdate));
        int d2 = Integer.parseInt(formatter.format(nowDate));
        int age = (d2 - d1) / 10000;
        friend_asl.setText(confirmedFriend.getDest_user().getGender() + ", " + age);
    } catch (ParseException e) {
        e.printStackTrace();
    }

    friend_name.setText(confirmedFriend.getDest_user().getFirstName() + " " + confirmedFriend.getDest_user().getLastName());


    return convertView;

}

public String getMail() {
    return mail;
}

public void setMail(String mail) {
    this.mail = mail;
}

Solution

  • If you want to do this in the Fragment then update the ArrayAdapter's list elements and call notifyDataSetChanged() on the adapter which will refresh the list.

    In your case:

    1. Add a new variable or use an existing variable in ConfirmedFriend.
    2. Update that variable in onConfirmedFriendsReceived().
    3. After updating the mConfirmedFriends list pass it to the adapter.
    4. Call notifyDatasetChanged() in the adapter or from the fragment.
    5. In getView() method of your ArrayAdapter set the ConfirmedFriend's variable to the TextView.