0

来自后端支持论坛。“此支持论坛仅针对与 Backendless 相关的问题。我们的 API 和后端服务之外的任何一般问题均不在支持范围内。请考虑发布到 stackoverflow.com 和/或 Android 论坛。” 马克·皮勒。

所以我在这里发布我的问题。在后端支持论坛上,我得到了一些宝贵的帮助来保存和检索关系,但现在我面临着“赞”按钮的另一个问题。我正在开发一个社交应用程序,其中有 3 个按钮:Like Comment Share。链接在我的后端支持线程: http: //support.backendless.com/topic/some-questions-regarding-data-loading-in-recyclerview-android 现在我正在尝试让 Like 按钮工作,但我面临以下问题:

如果您查看以下代码和我附上的屏幕截图,您会看到有一个未填充的“喜欢”心形按钮,这意味着我没有为该帖子点赞。在 2 号处,还有另一个按钮被填满,我点击了喜欢它,应用程序将我添加到喜欢该帖子的用户列表中。

if (user.getObjectId().equals(userId)) {

holder.like.setBackgroundResource(R.drawable.ic_star_rate_on);

holder.like.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

showToast();

}

});

} else {

holder.like.setBackgroundResource(R.drawable.ic_star_rate_off);

//onclick in another function: setLike(holder.like,holder.likes,feeds);

}

但问题是点击空心是行不通的。我尝试创建一个 toast 以检查单击是否有效并且 toast 没有出现。

但是,如果我单击我喜欢的项目(填充心形图标),它会向我显示我放置的吐司,以检查它是否听我的点击......

我尝试调试该应用程序,但调试窗口中没有出现任何内容……一切似乎都很正常,但无法找出代码有什么问题。我的适配器类如下:

public class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.FeedsHolder> {

private List<Feeds> list;

private Context context;

private static String TAG = "MainActivity";

public FeedAdapter(Context context, List<Feeds> list) {

this.context = context;

this.list = list;

}

@Override

public FeedsHolder onCreateViewHolder(ViewGroup parent, int viewType) {

View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_item, parent, false);

return new FeedsHolder(view);

}

@Override

public void onBindViewHolder(final FeedsHolder holder, int position) {

//Starting Feeds

final Feeds feeds = list.get(position);

//Name

holder.name.setText(feeds.getOwner());

//Profile picture

holder.profilePictureURL = feeds.getProfilePictureURL();

//Image

holder.imageURL = feeds.getImageUrl();

//Getting date

Date myD = feeds.getCreated();

long ddate = myD.getTime();

String myDate = String.valueOf(DateUtils.getRelativeTimeSpanString(ddate, System.currentTimeMillis(), DateUtils.SECOND_IN_MILLIS));

holder.timeAgo.setText("• " + myDate);

//Get total likes

final int i = feeds.getLikes();

//Query

QueryOptions options = new QueryOptions();

options.setRelated( Arrays.asList( "usersThatLike" ) );

BackendlessDataQuery query = new BackendlessDataQuery();

query.setQueryOptions( options );

// getting all saved feeds with related users

Backendless.Data.of(Feeds.class).find(query, new AsyncCallback<BackendlessCollection<Feeds>>() {

@Override

public void handleResponse(BackendlessCollection<Feeds> response) {

String userId = Backendless.UserService.CurrentUser().getObjectId();

for (Feeds feed: response.getCurrentPage()) {

List<BackendlessUser> likedUsers = feeds.getUsersThatLike();

for (BackendlessUser user : likedUsers)

if (user.getObjectId().equals(userId)) {

Log.d(TAG, "No -------------------------------------");

holder.like.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.ic_star_rate_on));

holder.like.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Toast.makeText(context, "You already like this item", Toast.LENGTH_SHORT).show();

}

});

} else {

holder.like.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.ic_star_rate_off));

holder.like.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Log.d(TAG, "It should work +++++++++++++++++++++++++++++++");

// getting current user

Toast.makeText(context, "Arrived", Toast.LENGTH_SHORT).show();

BackendlessUser currentUser = Backendless.UserService.CurrentUser();

// adding current user as one who "liked" feed, you should implement "adding" by yourself

List<BackendlessUser> list = new ArrayList<>();

list.add(currentUser);

feeds.setUsersThatLike(list);

holder.like.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.ic_star_rate_on));

feeds.setLikes(i + 1);

Backendless.Data.of(Feeds.class).save(feeds, new AsyncCallback<Feeds>() {

@Override

public void handleResponse(Feeds feeds) {

int likes = feeds.getLikes();

if (likes == 1) {

holder.likes.setText(i + 1 + " like");

} else {

holder.likes.setText(i + 1 + " likes");

}

}

@Override

public void handleFault(BackendlessFault backendlessFault) {

}

});

}

});

}

}

}

@Override

public void handleFault(BackendlessFault backendlessFault) {

}

});

holder.status.setText(feeds.getStatus());

String thisString = "no";

String myImageString = "no";

Picasso.with(context).load(holder.profilePictureURL).placeholder(R.drawable.placeholder).into(holder.profilePicture);

String image = feeds.getIsImageUrlEmpty();

if (!image.equals(myImageString)) {

holder.image.setVisibility(View.GONE);

holder.tagStatusBottom.setVisibility(View.VISIBLE);

holder.tagImageBottom.setVisibility(View.GONE);

} else {

holder.image.setVisibility(View.VISIBLE);

holder.tagStatusBottom.setVisibility(View.GONE);

holder.tagImageBottom.setVisibility(View.VISIBLE);

Picasso.with(context).load(holder.imageURL).placeholder(R.drawable.placeholder).into(holder.image);

}

String myString = feeds.getIsTagEmpty();

if (myString.equals(thisString)){

holder.tagImageBottom.setVisibility(View.VISIBLE);

if (!image.equals(myImageString)) {

holder.image.setVisibility(View.GONE);

holder.tagStatusBottom.setVisibility(View.VISIBLE);

holder.tagImageBottom.setVisibility(View.GONE);

} else {

holder.image.setVisibility(View.VISIBLE);

holder.tagStatusBottom.setVisibility(View.GONE);

holder.tagImageBottom.setVisibility(View.VISIBLE);

Picasso.with(context).load(holder.imageURL).placeholder(R.drawable.placeholder).into(holder.image);

}

} else {

holder.tagImageBottom.setVisibility(View.GONE);

holder.tagStatusBottom.setVisibility(View.GONE);

}

String str = feeds.getTag();

ArrayList<int[]> hashtagSpans1 = getSpans(str, '#');

SpannableString commentsContent1 =

new SpannableString(str);

setSpanComment(commentsContent1, hashtagSpans1) ;

holder.tagImageBottom.setText(commentsContent1);

holder.tagStatusBottom.setText(commentsContent1);

holder.tagImageBottom.setMovementMethod(LinkMovementMethod.getInstance());

int likes = feeds.getLikes();

if (likes == 1) {

holder.likes.setText(i +" like");

} else {

holder.likes.setText(i +" likes");

}

}

public ArrayList<int[]> getSpans(String body, char prefix) {

ArrayList<int[]> spans = new ArrayList<int[]>();

Pattern pattern = Pattern.compile(prefix + "\\w+");

Matcher matcher = pattern.matcher(body);

// Check all occurrences

while (matcher.find()) {

int[] currentSpan = new int[2];

currentSpan[0] = matcher.start();

currentSpan[1] = matcher.end();

spans.add(currentSpan);

}

return spans;

}

private void setSpanComment(SpannableString commentsContent, ArrayList<int[]> hashtagSpans) {

for(int i = 0; i < hashtagSpans.size(); i++) {

int[] span = hashtagSpans.get(i);

int hashTagStart = span[0];

int hashTagEnd = span[1];

commentsContent.setSpan(new Hashtag(context),

hashTagStart,

hashTagEnd, 0);

}

}

@Override

public int getItemCount() {

return list.size();

}

这是我的 Feed 课程:

public class Feeds

{

private String owner;

private String tag;

private String profilePictureURL;

private String imageURL;

private Date created;

private Date updated;

private String status;

private int likes;

private String isTagEmpty;

private String isImageUrlEmpty;

private List<BackendlessUser> usersThatLike;

public String getOwner()

{

return owner;

}

public void setOwner( String owner )

{

this.owner = owner;

}

public int getLikes()

{

return likes;

}

public void setLikes ( int likes )

{

this.likes = likes;

}

public String getIsTagEmpty()

{

return isTagEmpty;

}

public void setIsTagEmpty ( String isTagEmpty )

{

this.isTagEmpty = isTagEmpty;

}

public String getIsImageUrlEmpty()

{

return isImageUrlEmpty;

}

public void setIsImageUrlEmpty ( String isImageUrlEmpty )

{

this.isImageUrlEmpty = isImageUrlEmpty;

}

public String getStatus()

{

return status;

}

public void setStatus( String status )

{

this.status = status;

}

public String getTag()

{

return tag;

}

public void setTag( String tag )

{

this.tag = tag;

}

public String getProfilePictureURL()

{

return profilePictureURL;

}

public void setProfilePictureURL ( String profilePictureURL )

{

this.profilePictureURL = profilePictureURL;

}

public String getImageUrl()

{

return imageURL;

}

public void setImageUrl ( String imageURL )

{

this.imageURL = imageURL;

}

public Date getCreated()

{

return created;

}

public Date getUpdated()

{

return updated;

}

public List<BackendlessUser> getUsersThatLike() {

return usersThatLike;

}

public void setUsersThatLike(List<BackendlessUser> usersThatLike) {

this.usersThatLike = usersThatLike;

}

}

你能帮我吗?

编辑:在下面的答案中实现代码后它不起作用。这就是我编辑代码的方式:

    //Skipped previous code. Posted only the changed code
Backendless.Data.of(Feeds.class).find(query, new AsyncCallback<BackendlessCollection<Feeds>>() {
                @Override
                public void handleResponse(final BackendlessCollection<Feeds> feedsBackendlessCollection) {

//Suggested by sihao
                    holder.like.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            String userId = Backendless.UserService.CurrentUser().getObjectId();

                            for (Feeds feed: feedsBackendlessCollection.getCurrentPage()) {

                                List<BackendlessUser> likedUsers = feeds.getUsersThatLike();

                                for (BackendlessUser user : likedUsers)

                                    if (user.getObjectId().equals(userId)) {

                                        Toast.makeText(context,"You already liked this item",Toast.LENGTH_SHORT).show();
                                    } else {
                                        // getting current user

                                        BackendlessUser currentUser = Backendless.UserService.CurrentUser();

    // adding current user as one who "liked" feed, you should implement "adding" by yourself

                                        List<BackendlessUser> list = new ArrayList<>();

                                        list.add(currentUser);

                                        feeds.setUsersThatLike(list);

                                        holder.like.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.ic_star_rate_on));

                                        feeds.setLikes(i + 1);

                                        Backendless.Data.of(Feeds.class).save(feeds, new AsyncCallback<Feeds>() {
                                            @Override
                                            public void handleResponse(Feeds feeds) {
                                                int likes = feeds.getLikes();

                                                if (likes == 1) {

                                                    holder.likes.setText(i + 1 + " like");

                                                } else {

                                                    holder.likes.setText(i + 1 + " likes");

                                                }
                                            }

                                            @Override
                                            public void handleFault(BackendlessFault backendlessFault) {

                                            }
                                        });
                                    }
                            }
                        }
                    });
                }

                @Override
                public void handleFault(BackendlessFault backendlessFault) {

                }
            });

更新:这些天我试图解决这个问题并得到了一个(好)的想法。我成功地将按钮背景从空心更改为填充用户喜欢的元素的心。我得到了以下想法:检查心脏是空的还是充满的。因此,在活动加载时,我的应用程序从“usersThatLike”列获取数据,如果用户存在于后端列表中,则设置填充心可绘制,如果不存在则设置为空心绘制。所以现在我正在尝试对可绘制对象进行检查。如果心脏比显示吐司“你已经喜欢这个项目”,否则将喜欢的项目添加到项目并将用户添加到当前项目的“usersThatLike”列。但它正在为所有项目返回“充满”的心。我的意思是说,即使可绘制的心脏是空的,它也会返回它'

//*** Skipped the query code. In handleResponse:
    String userId = Backendless.UserService.CurrentUser().getObjectId();
                    for (Feeds feed: response.getData()) {
                        feed = list.get(position);

                        List<BackendlessUser> likedUsers = feed.getUsersThatLike();

                        for (BackendlessUser user : likedUsers)
                            if (user.getObjectId().equals(userId)) {
                                holder.like.setBackgroundResource(R.drawable.ic_star_rate_on);
                            } else if (!user.getObjectId().equals(userId)) {
                                holder.like.setBackgroundResource(R.drawable.ic_star_rate_off);
                            }
                    }

而不是在handleResponse之外,在查询代码之后的正常onBindViewHolder中,我正在检查drawable,如下所示:

//***HERE IS THE QUERY
    Backendless.Data.of(Feeds.class).find(query, new AsyncCallback<BackendlessCollection<Feeds>>() {

            //***SKIPPED FOR BREVITY 

        });

//***HERE IS THE CHECK

        holder.like.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (holder.like.getBackground() != context.getDrawable(R.drawable.ic_star_rate_off)){
                toast();
            } else {
                setLike();
            }
        }
    });
4

2 回答 2

1

我相信你的问题就在这里。

参考上面给出的代码:

//****PART I: NOTICE HERE****//
if (user.getObjectId().equals(userId)) {

     holder.like.setBackgroundResource(R.drawable.ic_star_rate_on);

     //****YOUR CLICK LISTENER*****//
     holder.like.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             showToast();
          }

      });

  //****PART II: NOTICE HERE****//
 } else {

  holder.like.setBackgroundResource(R.drawable.ic_star_rate_off);

  //onclick in another function: setLike(holder.like,holder.likes,feeds);

}

如果您查看第 I 部分和第 II 部分所示的两个部分,您将意识到如果用户之前喜欢该帖子,您只附加了按钮的 ClickListener。

您的解决方案是将这个 ClickListener 移出范围,移到更一般的地方。

例如:

//****YOUR CLICK LISTENER*****//
holder.like.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       showToast();
   }

});

//****PART I: NOTICE HERE****//
if (user.getObjectId().equals(userId)) {

     holder.like.setBackgroundResource(R.drawable.ic_star_rate_on);

  //****PART II: NOTICE HERE****//
 } else {

  holder.like.setBackgroundResource(R.drawable.ic_star_rate_off);

  //onclick in another function: setLike(holder.like,holder.likes,feeds);

}

编辑:

从您的代码中,您似乎正在尝试将两个 ClickListener 附加到同一个按钮。

而不是这样做,你应该尝试这种方法。

  • 首先,使用我提供的修改后的示例。(添加一个通用的点击监听器)

  • 在您的 ClickListener 中,以这种方式实现它。

     //****YOUR CLICK LISTENER*****//
     holder.like.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             if (user.getObjectId().equals(userId)) {
                 .... do your stuff here
             } else {
                 .... do other stuff here
             }
          }
    
      });
    
于 2016-04-10T17:52:17.700 回答
0

更新:

大家好,我终于找到了一个非常棘手的解决方案来解决我的问题。我能够将用户保存到“usersThatLike”列并在特定项目上设置类似。但是每次我单击“喜欢”按钮时,它都会显示“你已经喜欢它”的祝酒词,只有当我出现在 usersThatLike 列表中时才应该显示它,所以出现了问题。我使用以下技巧来解决这个问题:在我的 RecyclerView 适配器中,我像这样查询我的类:

QueryOptions options = new QueryOptions();

    options.setRelated( Arrays.asList( "usersThatLike" ) );

    BackendlessDataQuery query = new BackendlessDataQuery();

    query.setQueryOptions( options );

    Backendless.Data.of(Feeds.class).find(query, new AsyncCallback<BackendlessCollection<Feeds>>() {

        @Override

        public void handleResponse(BackendlessCollection<Feeds> response) {
            String userId = Backendless.UserService.CurrentUser().getObjectId();
            for (Feeds feed: response.getData()) {
                feed = list.get(position);

                List<BackendlessUser> likedUsers = feed.getUsersThatLike();

                for (BackendlessUser user : likedUsers)
                    if (user.getObjectId().equals(userId)) {
                        holder.like.setBackgroundResource(R.drawable.ic_star_rate_on);
                    } else if (!user.getObjectId().equals(userId)) {
                        holder.like.setBackgroundResource(R.drawable.ic_star_rate_off);
                    }
            }

        }

        @Override

        public void handleFault(BackendlessFault backendlessFault) {

        }

    });

如您所见,如果查询返回该用户不在列表中并且如果用户在那里,我将可绘制对象设置为关闭星号。

所以在那之后我是如何解决这个问题的。在我的查询之外,我创建了以下检查:

holder.likeLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (holder.like.getBackground().getConstantState() != ContextCompat.getDrawable(context, R.drawable.ic_star_rate_off).getConstantState()){
                toast();
            } else {
                setLike();
            }
        }
    });

在上面的代码中,我获得了按钮背景并将其与我的可绘制文件夹中的图像进行比较,并关闭星号。如果like按钮带有star_off,它将设置like并将用户添加到usersThatLike列表中。否则显示敬酒:“你已经喜欢这个项目”

希望它可以帮助其他人并节省他们的时间,因为我在这个问题上花了很多时间。

问候


老答案:

回复 sihao 的评论:@sihao 如果你查看我的第一篇文章,你会看到:

    if (user.getObjectId().equals(userId)) {

    Log.d(TAG, "No -------------------------------------");

    holder.like.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.ic_star_rate_on));

// FIRST ONCLICK LISTENER
    holder.like.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

    Toast.makeText(context, "You already like this item", Toast.LENGTH_SHORT).show();

    }

    });

    } else {

    holder.like.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.ic_star_rate_off));

// SECOND ONCLICK LISTENER
    holder.like.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

    Log.d(TAG, "It should work +++++++++++++++++++++++++++++++");

    // getting current user

    Toast.makeText(context, "Arrived", Toast.LENGTH_SHORT).show();

    BackendlessUser currentUser = Backendless.UserService.CurrentUser();

    // adding current user as one who "liked" feed, you should implement "adding" by yourself

    List<BackendlessUser> list = new ArrayList<>();

    list.add(currentUser);

    feeds.setUsersThatLike(list);

    holder.like.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.ic_star_rate_on));

    feeds.setLikes(i + 1);

    Backendless.Data.of(Feeds.class).save(feeds, new AsyncCallback<Feeds>() {

    @Override

    public void handleResponse(Feeds feeds) {

    int likes = feeds.getLikes();

    if (likes == 1) {

    holder.likes.setText(i + 1 + " like");

    } else {

    holder.likes.setText(i + 1 + " likes");

    }

    }

    @Override

    public void handleFault(BackendlessFault backendlessFault) {

    }

    });

    }

    });
于 2016-04-10T18:32:06.293 回答