Подтвердить что ты не робот

Android - добавление просмотров в изображения не обновляется - onClick

Резюме

Когда пользователь нажимает на элемент RecyclerView, я хотел бы добавить теги к этому изображению из информации, которая была сохранена в BaaS [Sashido] (координаты X, координаты Y и имя тега), Но проблема, с которой я столкнулась, - это не нахождение позиции. Я создаю тост при щелчке изображения, он показывает правильное положение, соответствующее самому представлению. (ноль для начала, так далее и т.д.)

Но как обновить позицию после того, как пользователь нажмет на другой элемент в списке, так что теги, которые соответствуют позиции в массиве в Sashido, соответствуют позиции в RecyclerView, потому что в настоящий момент первая строка в классе Sashido заполняет все изображения тегами строк.

Мое предположение состояло в том, чтобы передать позицию методу getTagInformation(), используя getLayoutPosition(), чтобы при вызове массива objects.get(position) он получил ту же позицию для класса Sashido, но это не так. Я чувствую, что адаптер не должен обновляться после того, как пользователь нажал на новый элемент.

onBindViewHolder:

@Override
public void onBindViewHolder(RecyclerViewHolderPreviousPosts holder, int position) {
    holder.bind(previousPostsList.get(position), listener);
}

onBind:

void bind(final PreviousPostsDataModel model, final OnItemClickListener listener) { ...

uploadedImage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                        if (count == 0) {
                            imageid = model.getImageId();
                            Toast.makeText(App.getContext(), "Image ID: " + imageid, Toast.LENGTH_SHORT).show();
                            Toast.makeText(App.getContext(), "Position: " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
                            getTagInformation(getLayoutPosition());
                        } else {
                            Log.e("qwert", "" + imageid);
                            imageContainer.removeAllViews();
                            imageContainer.addView(uploadedImage);
                            count = 0;
                        }
                }
            });
... }

getTagИнформация:

private void getTagInformation(final int position) {
                ParseQuery<ParseObject> query = ParseQuery.getQuery("FashionFeed");
                query.findInBackground(new FindCallback<ParseObject>() {
                    @Override
                    public void done(List<ParseObject> objects, ParseException e) {
                        if (e == null) {
                            Toast.makeText(context, "" + position, Toast.LENGTH_SHORT).show();
                            JSONArray tagNamesArray = objects.get(position).getJSONArray("tagName");
                            JSONArray posXArray = objects.get(position).getJSONArray("tagPointX");
                            JSONArray posYArray = objects.get(position).getJSONArray("tagPointY");

                            for (int i = 0; i < tagNamesArray.length(); i++) {
                                for (int t = 0; t < tagNamesArray.length(); t++) {
                                    tagNames.add(tagNamesArray.optString(t));
                                    tagXPositions.add(posXArray.optString(t));
                                    tagYPositions.add(posYArray.optString(t));

                                }

                                for (int o = 0; o < tagNamesArray.length(); o++) {
                                    tag = new TextView(App.getContext());
                                    tag.setX(Float.parseFloat(tagXPositions.get(o)));
                                    tag.setY(Float.parseFloat(tagYPositions.get(o)));
                                    tag.setText(tagNames.get(o));
                                    tag.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                                    tag.setMaxLines(1);
                                    tag.setTextSize(11);
                                    tag.setClickable(true);
                                    tag.setHintTextColor(Color.WHITE);
                                    tag.setTextColor(Color.WHITE);
                                    tag.setBackgroundResource(R.drawable.tags_rounded_corners);
                                    imageContainer.addView(tag);
                                    count = 1;
                                }
                            }
                        } else {
                            Toast.makeText(context, "" + e.getMessage(), Toast.LENGTH_LONG).show();
                        }
                    }
                });
        }

Я также пробовал

public void getTagInformation(String imageid) {
ParseQuery query = ParseQuery.getQuery("FashionFeed");
query.WhereEqualTo("objectId", imageId);
....
}

с imageId, переданным в метод, а также я вручную введя objectId, который будет соответствовать, он все равно будет генерировать теги, принадлежащие этому objectId. просто не кажется, что этот запрос проходит через все объекты. Просто получая информацию тега от этого одного объекта, а затем устанавливая все изображения с этими тегами.

если вам нужно, чтобы я предоставил больше кода, я более чем счастлив.

4b9b3361

Ответ 1

Решил проблему. Дело было не столько в том, что позиция была неправильной, а потому, что я пытался найти теги, прежде чем я заполнил список изображений из-за обратного вызова Parse FindInBackground(), он был заселен слишком поздно.

Решение заключалось в том, что я получил JSONArray, который содержал имена тегов, x-координаты и координаты y внутри исходного запроса, который заполнял исходный список изображений. Таким образом, они выполнялись одновременно, затем я передавал значения JSONArray в model, который затем передавался функции bind() в Adapter.

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

Это сделало так, что каждый раз, когда изображение было нажато, он всегда находил первый объект в базе данных и назначал его выбранному изображению. [из-за события щелчка, запускающего функцию getTagInformation()). Благодаря автоматизации метода getTagInformation в Bind функции ViewHolder, я смог заполнить каждое изображение правильными тегами и продолжить его манипулирование с помощью onClickListener, назначенного для изображения, как показано ниже:

Держатель RecyclerView:

public class RecyclerViewHolderPreviousPosts extends RecyclerView.ViewHolder implements View.OnClickListener {
        // View holder for gridview recycler view as we used in listview
        public TextView createdAt;
        public ImageView uploadedImage;
        public TextView caption;
        TextView number_of_likes;
        TextView number_of_comments;
        TextView number_of_tags;
        public ImageView comments;
        public RelativeLayout imageContainer;


    RecyclerViewHolderPreviousPosts(View view) {
        super(view);
        // Find all views ids
        this.createdAt = (TextView) view
                .findViewById(R.id.created_date);
        this.uploadedImage = (ImageView) view
                .findViewById(R.id.image);
        this.caption = (TextView) view
                .findViewById(R.id.caption_post);
        this.number_of_likes = (TextView) view
                .findViewById(R.id.number_of_likes);
        this.number_of_comments = (TextView) view
                .findViewById(R.id.number_of_comments);
        this.number_of_tags = (TextView) view
                .findViewById(R.id.number_of_tags);
        this.comments = (ImageView) view
                .findViewById(R.id.comments_image);
        this.imageContainer = (RelativeLayout) view
                .findViewById(R.id.image_container);
        view.setOnClickListener(this);
    }

    void bind(PreviousPostsDataModel model1, final int position) { ....
        model = previousPostsList.get(position);
        getTagInformation();
....}

    private void getTagInformation() {
        for (int o = 0; o < model.getTagSize(); o++) {
            tag = new TextView(App.getContext());
            tag.setX(Float.parseFloat(model.getXpoints(o)));
            tag.setY(Float.parseFloat(model.getYpoints(o)));
            Log.e("x", "" + tag.getX());
            Log.e("y", "" + tag.getY());
            tag.setText(model.getTagName(o));
            tag.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            tag.setMaxLines(1);
            tag.setTextSize(11);
            tag.setClickable(true);
            tag.setHintTextColor(Color.WHITE);
            tag.setTextColor(Color.WHITE);
            tag.setBackgroundResource(R.drawable.tags_rounded_corners);
            imageContainer.addView(tag);
            tags.add(tag);
        }
    }

    @Override
    public void onClick(View v) {
        if (count == 0) {
            for (int i = 0; i < tags.size(); i++) {
                tags.get(i).setVisibility(View.INVISIBLE);
            }
            count = 1;
        }
        else {
            for (int j = 0; j < tags.size(); j++) {
                tags.get(j).setVisibility(View.VISIBLE);
            }
            count = 0;
        }
    }
}

Фрагмент профиля [Исходный запрос]:

private void populateSelectedUserRecyclerView(String objectid) {
        ParseQuery<ParseObject> query = ParseQuery.getQuery("FashionFeed");
        query.whereEqualTo("uploader", ParseObject.createWithoutData("_User", objectid));
        query.orderByDescending("createdAt");
        Log.e("get order", "ordered");
        query.findInBackground(new FindCallback<ParseObject>() {
            @Override
            public void done(List<ParseObject> objects, ParseException e) {
                Log.e("gets done", "gets into done");
                if(e == null) {
                    if (objects.size() > 0) {
                        Log.e("does it get here", "it got here");

                        latestPostList = new ArrayList<>();
                        for (ParseObject j : objects) {
                            JSONArray tagNamesArray = j.getJSONArray("tagName");
                            JSONArray posXArray = j.getJSONArray("tagPointX");
                            JSONArray posYArray = j.getJSONArray("tagPointY");
                            latestPostList.add(new PreviousPostsDataModel(tagNamesArray, posXArray, posYArray));
                        }
                    }
                    else {
                        no_follow_display.setVisibility(View.VISIBLE);
                        no_follow_display.setText(R.string.no_posts);
                        no_follow_display.bringToFront();
                        recyclerView.setVisibility(View.GONE);
                    }

                    adapter = new RecyclerViewAdapterPreviousPosts(getActivity(), latestPostList, listener);
                    recyclerView.setAdapter(adapter);// set adapter on recyclerview

                    adapter.notifyDataSetChanged();
                }
                else {
                    Log.e("failed", "failed" + e.getMessage());
                }
            }
        });
    }

Спасибо за вашу помощь.

Ответ 2

Привет @BIW, пожалуйста, следуйте ниже ссылка

В onBindViewHolder вы добавляете слушателя каждый раз, поэтому он возвращает тот же объект каждый раз, когда шаблон recyclerView ViewHolder использует тот же объект для рендеринга элемента recyclerView в onBindViewHolder. Поэтому вам нужно добавить, когда вы создаете объект-держатель и устанавливаете для него слушателя, чтобы вы получили правильную позицию.

package com.subbu.moviemasti.adapter;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.squareup.picasso.Picasso;
import com.subbu.moviemasti.Constants;
import com.subbu.moviemasti.R;
import com.subbu.moviemasti.entities.Movie;

import java.util.List;

import butterknife.Bind;
import butterknife.ButterKnife;

/**
 * Created by subrahmanyam on 25-11-2015.
 */
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder> {

    private final List<Movie> movieList;
    private onRecyclerViewItemClickListener mItemClickListener;

    public MovieAdapter(List<Movie> movieList) {
        this.movieList = movieList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.grid_item, null);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        final Movie movie = movieList.get(position);
        String imageUrl = Constants.MOVIE_POSTER_BASE_URL + movie.getPosterPath();
        if (imageUrl != null) {
            Picasso.with(holder.posterImage.getContext()).load(imageUrl).
                    placeholder(R.drawable.img_default).
                    into(holder.posterImage);
        }
    }

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

    @Override
    public int getItemCount() {
        return movieList.size();
    }

    public void setOnItemClickListener(onRecyclerViewItemClickListener mItemClickListener) {
        this.mItemClickListener = mItemClickListener;
    }

    public interface onRecyclerViewItemClickListener {
        void onItemClickListener(View view, int position);
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        @Bind(R.id.poster)
        ImageView posterImage;

        public ViewHolder(View view) {
            super(view);
            ButterKnife.bind(this, view);
            view.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            mItemClickListener.onItemClickListener(v, getAdapterPosition());
        }
    }

}

Где мы создаем объект adaper, оттуда нам нужно установить прослушиватель например adapter.setOnItemClickListener(this)

class MyActivity extendsActivity implements onRecyclerViewItemClickListener {
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
    manager = new GridLayoutManager(getActivity(), cols);
            gridView.setLayoutManager(manager); 
gridView.setAdapter(adapter);
adapter.setOnItemClickListener(this);
}
 @Override
        public void onItemClickListener(View view, int position) {
            //Do wantever you want to do
        }
}

Из класса ViewHolder нам нужно передать position в recyclerView, или мы можем написать код, который вам нужно выполнить, когда нажимаете на элемент.

Ответ 3

Если я правильно понимаю вопрос, проблема в том, что ParseQuery не возвращает объекты в том же порядке. Таким образом, предположения о том, что положение объекта в вашем RecycleView такое же, как в ParseDatabase, неверно.

Если вы хотите получить TAG от Sashido, вы должны сначала сделать некоторые отношения с изображениями, например, в дополнительном столбце. Затем сделайте запрос белым дополнительным параметром, например:

private static final String UNIQ_TAG_ID= "tagId"; query.whereContainedIn(UNIQ_TAG_ID, id);

или получить все ParseObjects, как и сейчас, и найти TAG, которые соответствуют вашему изображению, а затем взять информацию.