Я новичок в этом материале, поэтому я надеюсь, что это не смешной вопрос ... У меня есть список и все элементы, включая видео, numOfLikes (textview), нравится и не нравится (кнопки). Когда я нажимаю кнопку "Нравится" или "Не нравится", я пытаюсь изменить фон кнопки, но это меняет фон всех кнопок "Нравится / не нравится" в представлении списка.

То же самое происходит, когда я пытаюсь включить кнопку «Не нравится», когда я нажимаю кнопку «Нравится», это отключает все кнопки «Не нравится» в списке.

Код:

public class FeedAdapter extends ArrayAdapter<Feed> {

Context context;
ArrayList<Feed> feedsList;
ArrayList<String> listOfItems;
Dialog dialog;

public FeedAdapter(Context context, int resource, ArrayList<Feed> feeds) {
    super(context, resource, feeds);
    this.context = context;
    this.feedsList = feeds;
}

public FeedAdapter(Context context, ArrayList<Feed> feeds){
    super(context, R.layout.feed_listitem, feeds);
    this.context = context;
    this.feedsList = feeds;
}

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

    if(convertView == null){
        convertView = LayoutInflater.from(context).inflate(R.layout.feed_listitem, parent, false);
        holder = new FeedHolder();

        holder.titleTextView = (TextView) convertView.findViewById(R.id.feed_title_textView);
        holder.usernameTextView = (TextView) convertView.findViewById(R.id.feed_name_textview);
        holder.likesTextView = (TextView) convertView.findViewById(R.id.feed_likes_textview);
        holder.likeButton = (Button) convertView.findViewById(R.id.feed_like_button);
        holder.unlikeButton = (Button) convertView.findViewById(R.id.feed_unlike_button);
        holder.video = (VideoView) convertView.findViewById(R.id.feed_post_videoView);
        holder.frameLayout = (FrameLayout) convertView.findViewById(R.id.feed_placeholder_framelayout);

        holder.frameLayout.setTag(holder.video);
        holder.likeButton.setTag(holder.unlikeButton);
        holder.unlikeButton.setTag(holder.likeButton);
        convertView.setTag(holder);
    } else{
        holder = (FeedHolder) convertView.getTag();
        holder.frameLayout.setTag(holder.video);
        holder.likeButton.setTag(holder.unlikeButton);
        holder.unlikeButton.setTag(holder.likeButton);
    }

    holder.titleTextView.setText(feedsList.get(position).getTitle());
    holder.usernameTextView.setText(feedsList.get(position).getUsername());
    holder.likesTextView.setText(TrendliContract.showNumInNumK(feedsList.get(position).getLikesInLong()));

    holder.titleTextView.setTypeface(TrendliContract.helvetica);
    holder.usernameTextView.setTypeface(TrendliContract.helvetica);
    holder.likesTextView.setTypeface(TrendliContract.helvetica);

    holder.frameLayout.setBackground(feedsList.get(position).getDrawable());
    holder.video.setVisibility(View.INVISIBLE);
    holder.video.setMediaController(new MediaController(context));  
    holder.video.setVideoURI(Uri.parse(feedsList.get(position).getVideoImageGif()));
    holder.video.setLayoutParams(new FrameLayout.LayoutParams(TrendliContract.screenW,
            TrendliContract.screenW));

    postImageViewOnClickListener(holder);

    holder.likeButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Feed f = feedsList.get(position);
            //Button b = ((Button) v.getTag());
            if(f.isLikePressed() == false){
                new TrendliContract.Like().execute(f);
                f.setLikePressed(true);
                int numOfLikes = Integer.parseInt(holder.likesTextView.getText().
                        toString().replace(" ", ""));
                holder.likesTextView.setText(String.valueOf(++numOfLikes));
                //v.setBackgroundColor(R.color.black);
                //b.setEnabled(false);
            } else{
                new TrendliContract.UnLike().execute(f);
                f.setLikePressed(false);
                int numOfLikes = Integer.parseInt(holder.likesTextView.getText().
                        toString().replace(" ", ""));
                holder.likesTextView.setText(String.valueOf(--numOfLikes));
                //v.setBackgroundColor(R.color.transparent);
                //b.setEnabled(true);
            }
        }

    });

    holder.unlikeButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Feed f = feedsList.get(position);
            //Button b = ((Button) v.getTag());
            if(f.isDislikePressed() == false){
                new TrendliContract.DisLike().execute(f);
                f.setDislikePressed(true);
                int numOfLikes = Integer.parseInt(holder.likesTextView.getText().toString().replace(" ", ""));
                holder.likesTextView.setText(String.valueOf(--numOfLikes));
                //v.setBackgroundColor(R.color.black);
                //b.setEnabled(false);
            } else{
                new TrendliContract.UnDisLike().execute(f);
                f.setDislikePressed(false);
                int numOfLikes = Integer.parseInt(holder.likesTextView.getText().toString().replace(" ", ""));
                holder.likesTextView.setText(String.valueOf(++numOfLikes));
                //v.setBackgroundColor(R.color.transparent);
                //b.setEnabled(true);
            }
        }
    });

    convertView.setTag(holder);
    return convertView;
}






private class FeedHolder{
    TextView titleTextView;
    TextView usernameTextView;
    TextView likesTextView;
    Button likeButton;
    Button unlikeButton;
    VideoView video;
    FrameLayout frameLayout;
}

}
0
OShiffer 3 Сен 2014 в 12:52

4 ответа

Лучший ответ

Вы не должны никогда изменять свойства представления элемента ListView в событии onClick.

Причина в том, что событие onClick вызывается из метода getView в другое время, и из-за системы повторного использования ListView эти затронутые свойства будут применены к переработанным представлениям, поэтому вы получаете нерелевантный полученные результаты.

Вместо этого вы должны сохранить свойства в массиве, а затем в методе getView использовать этот массив для применения свойств к представлениям ...

В классе Adapter

boolean[] buttonState;

В constructor:

buttonState = new boolean[feeds.size()];

В onClick:

buttonState[position] = false; // or true...

В getView:

holder.yourButton.setEnabled(buttonState[position]);
1
semsamot 3 Сен 2014 в 13:21
Он не применяет никаких изменений для setEnabled в getView
 – 
Rohan Chavan
8 Май 2017 в 14:21

В качестве варианта вы можете создать собственный класс кнопки, расширяющий Button и реализующий View.OnClickListener, а затем переопределив его метод onClick, чтобы установить фон, соответствующий флагу, например mPressed. После этого вы можете использовать этот класс для своих кнопок. Вот пример класса настраиваемой кнопки:

public class CustomButton extends Button implements View.OnClickListener {
    private boolean mPressed = false;
    private static final int mRegularBackID = R.drawable.button_up;
    private static final int mPressedBackID = R.drawable.button_down;

    public CustomButton( Context context ) {
        super( context );
    }
    public CustomButton( Context context, AttributeSet attrs ) {
        super( context, attrs );
    }
    public CustomButton( Context context, AttributeSet attrs, int defStyle ) {
        super( context, attrs, defStyle );
    }

    @Override
    public void onClick( View view ) {
        mPressed = !mPressed;
        this.setBackgroundResource( mPressed ? mPressedBackID : mRegularBackID );
    }

}

Вместо статических идентификаторов с возможностью рисования с флагом (как в моем примере) вы также можете использовать список состояний с возможностью рисования или конструктор с соответствующими элементами в качестве дополнительных параметров.

Вы можете использовать этот настраиваемый класс в XML с полным именем пакета, например

<my.own.project.package.CustomButton... />
1
Евгений Шевченко 3 Сен 2014 в 14:46

Просмотр передан в onClick(View v), по нему щелкнули объект Button, вы можете использовать его для изменения свойства Button.

public void onClick(View v) {
   Button b = ((Button)v);
   b.setEnabled(false);
}

Вы можете настроить свойство background для Button внутри вашего xml-макета. Даже вы можете определить вытягиваемый элемент xml, который будет определять различный фон для разных состояний, таких как: нажат, сфокусирован, отключен и т. Д. Сначала вам нужно определить селектор xml и установить его как фон кнопки:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/selected" android:state_pressed="true"/>
    <item android:drawable="@color/selected" android:state_selected="true"/>
    <item android:drawable="@android:color/transparent"/>
</selector>

Вместо цветов вы можете использовать доступные для рисования ресурсы (изображения или фигуры). Также вы можете определять различные состояния в этом списке. Будет использован первый элемент в селекторе, соответствующий текущему состоянию.

0
dasar 3 Сен 2014 в 13:08

Пытаться --

 likeButton.setBackgroundColor(R.color.transparent);
 unlikeButton.setEnabled(false);
0
user1626183user1626183 3 Сен 2014 в 13:10
Я думаю, что было бы более полезно для OP и других посетителей, если бы вы добавили некоторые пояснения к своему намерению.
 – 
Reporter
3 Сен 2014 в 13:45