Android - Backendless:点赞按钮问题
Android - Backendless: Issue with like button
来自后台支持论坛。 "This support forum is strictly for Backendless-related issues. Any general problems outside of our APIs and backend services are not covered by support. Please consider posting to whosebug.com and/or Android forums."马克皮勒。
所以我post在这里解决我的问题。
在 backendless 支持论坛上,我得到了一些宝贵的帮助来保存和检索关系,但现在我面临着另一个关于“赞”按钮的问题。
我正在开发一个社交应用程序,其中有 3 个按钮:喜欢评论分享。
Link 在我无尽的支持线程:
http://support.backendless.com/topic/some-questions-regarding-data-loading-in-recyclerview-android
现在我正在尝试使“赞”按钮起作用,但我面临以下问题:
如果你看下面的代码和我的屏幕截图 attached 你可以看到有一个没有填充的心形按钮,这意味着我没有点击那个按钮 post。在 2 号处有另一个按钮已填充,我点击喜欢它,该应用程序将我添加到这样的用户列表中 post。
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 没有显示。
但是如果我点击一个我喜欢的项目(心形图标填充),它会显示吐司,我会检查它是否听我的点击....
我尝试调试应用程序,但调试中没有显示任何内容window...一切似乎都很正常,但无法找出代码的问题所在。
我的适配器 class 如下:
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 class:
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) {
}
});
更新: 这些天我试图解决这个问题并得到了一个(不错的)想法。
我成功地将按钮背景从空心更改为充满用户喜欢的元素的心。我有以下想法:检查心脏是空的还是充满的。因此,在 activity 加载时,我的应用程序从 "usersThatLike" 列获取数据,如果用户出现在后端列表中,则设置填充心形可绘制对象,如果不存在,则设置空心可绘制对象。
所以现在我正在尝试对可绘制对象进行检查。
如果心已满而不是祝酒词 "You liked this item already" 否则将喜欢添加到项目并将用户添加到当前项目的 "usersThatLike" 列。
但它会为所有项目返回 "filled" 心。我的意思是说,即使心脏可绘制对象是空的,它也会返回它已填充,如果我单击填充的心脏可绘制对象,它会显示吐司,但如果心脏未填充,它将显示相同的吐司:
我的代码是:
//*** 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 中,我正在检查可绘制对象,如下所示:
//***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();
}
}
});
我相信你的问题出在这里。
参考你上面给出的代码:
//****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);
}
如果您查看第一部分和第二部分所示的两个部分,您会发现如果用户之前喜欢 post,您只会附加按钮的 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
}
}
});
更新:
大家好,
我终于找到了一个非常棘手的解决方案来解决我的问题。
我能够将用户保存到 "usersThatLike" 列并在特定项目上设置类似。但是每次我点击喜欢按钮时,它都会显示祝酒词 "You already liked it",只有当我出现在 usersThatLike 列表中时才应该显示,所以出现了问题。
我使用以下技巧来解决这个问题:
在我的 RecyclerView 适配器中,我这样查询 class:
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) {
}
});
如您所见,如果查询 returns 用户不在列表中,我将 drawable 设置为关闭,如果用户在列表中,则打开。
所以这就是我解决问题的方法。
在我的查询之外,我创建了以下检查:
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();
}
}
});
在上面的代码中,我获取了按钮背景,并将其与我的可绘制文件夹中的图片进行比较,星号已关闭。
如果点赞按钮带有 star_off,它将设置点赞并将用户添加到 usersThatLike 列表。否则敬酒:"You already liked this item"
希望它可以帮助其他人并节省他们的时间,因为我在这个问题上花了很多时间。
此致
旧答案:
回复sihao的评论:
@sihao 如果你检查我的第一个 post 你会看到:
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) {
}
});
}
});
来自后台支持论坛。 "This support forum is strictly for Backendless-related issues. Any general problems outside of our APIs and backend services are not covered by support. Please consider posting to whosebug.com and/or Android forums."马克皮勒。
所以我post在这里解决我的问题。 在 backendless 支持论坛上,我得到了一些宝贵的帮助来保存和检索关系,但现在我面临着另一个关于“赞”按钮的问题。 我正在开发一个社交应用程序,其中有 3 个按钮:喜欢评论分享。 Link 在我无尽的支持线程: http://support.backendless.com/topic/some-questions-regarding-data-loading-in-recyclerview-android 现在我正在尝试使“赞”按钮起作用,但我面临以下问题:
如果你看下面的代码和我的屏幕截图 attached 你可以看到有一个没有填充的心形按钮,这意味着我没有点击那个按钮 post。在 2 号处有另一个按钮已填充,我点击喜欢它,该应用程序将我添加到这样的用户列表中 post。
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 没有显示。
但是如果我点击一个我喜欢的项目(心形图标填充),它会显示吐司,我会检查它是否听我的点击....
我尝试调试应用程序,但调试中没有显示任何内容window...一切似乎都很正常,但无法找出代码的问题所在。 我的适配器 class 如下:
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 class:
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) {
}
});
更新: 这些天我试图解决这个问题并得到了一个(不错的)想法。 我成功地将按钮背景从空心更改为充满用户喜欢的元素的心。我有以下想法:检查心脏是空的还是充满的。因此,在 activity 加载时,我的应用程序从 "usersThatLike" 列获取数据,如果用户出现在后端列表中,则设置填充心形可绘制对象,如果不存在,则设置空心可绘制对象。 所以现在我正在尝试对可绘制对象进行检查。 如果心已满而不是祝酒词 "You liked this item already" 否则将喜欢添加到项目并将用户添加到当前项目的 "usersThatLike" 列。 但它会为所有项目返回 "filled" 心。我的意思是说,即使心脏可绘制对象是空的,它也会返回它已填充,如果我单击填充的心脏可绘制对象,它会显示吐司,但如果心脏未填充,它将显示相同的吐司: 我的代码是:
//*** 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 中,我正在检查可绘制对象,如下所示:
//***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();
}
}
});
我相信你的问题出在这里。
参考你上面给出的代码:
//****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);
}
如果您查看第一部分和第二部分所示的两个部分,您会发现如果用户之前喜欢 post,您只会附加按钮的 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 } } });
更新:
大家好, 我终于找到了一个非常棘手的解决方案来解决我的问题。 我能够将用户保存到 "usersThatLike" 列并在特定项目上设置类似。但是每次我点击喜欢按钮时,它都会显示祝酒词 "You already liked it",只有当我出现在 usersThatLike 列表中时才应该显示,所以出现了问题。 我使用以下技巧来解决这个问题: 在我的 RecyclerView 适配器中,我这样查询 class:
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) {
}
});
如您所见,如果查询 returns 用户不在列表中,我将 drawable 设置为关闭,如果用户在列表中,则打开。
所以这就是我解决问题的方法。 在我的查询之外,我创建了以下检查:
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();
}
}
});
在上面的代码中,我获取了按钮背景,并将其与我的可绘制文件夹中的图片进行比较,星号已关闭。 如果点赞按钮带有 star_off,它将设置点赞并将用户添加到 usersThatLike 列表。否则敬酒:"You already liked this item"
希望它可以帮助其他人并节省他们的时间,因为我在这个问题上花了很多时间。
此致
旧答案:
回复sihao的评论: @sihao 如果你检查我的第一个 post 你会看到:
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) {
}
});
}
});