来自后端支持论坛。 “此支持论坛主要针对Backendless相关问题。我们的API和后端服务之外的任何常见问题都不在支持范围内。请考虑发布到stackoverflow.com和/或Android论坛。”马克皮勒。
所以我在这里发布我的问题。 在后端支持论坛上,我得到了一些保存和检索关系的宝贵帮助,但现在我正面临着Like按钮的另一个问题。 我正在开发一个社交应用,其中有3个按钮:赞评论共享。 在我的后端支持线程链接: http://support.backendless.com/topic/some-questions-regarding-data-loading-in-recyclerview-android 现在我想尝试使用Like按钮,但我遇到了以下问题:
如果您查看以下代码并在屏幕截图中我attached,您可以看到有类似心脏按钮,它没有填充,这意味着我没有为该帖子打出类似内容。并且在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);
}
但问题是空心的点击不起作用。我试图创建一个吐司来检查点击是否有效并且吐司没有出现。
但是,如果我点击我喜欢的项目(心脏图标已填满),它会向我展示吐司,我会检查它是否听取了我的点击....
我尝试调试应用程序,调试窗口中没有任何内容......一切似乎都正常但无法找出代码的问题。 我的Adapter类如下:
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”列获取数据,并设置填充心脏可绘制如果用户出现在backendless和空心脏抽象的列表中(如果不存在)。 所以现在我正试图在drawable上创建一个检查。 如果心脏被填充而不是显示祝酒词“你已经喜欢这个项目”,那么就把它放到项目中并将用户添加到当前项目的“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();
}
}
});
答案 0 :(得分: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);
}
如果你看一下第一部分和第二部分所指出的两个部分,你就会发现如果用户以前喜欢这个帖子你只附加了按钮的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);
}
编辑:
从您的代码中,您似乎尝试将两个ClickListeners附加到同一个按钮。
您应该尝试这种方法,而不是这样做。
首先,使用我提供的修改示例。 (添加常规点击监听器)
在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
}
}
});
答案 1 :(得分:0)
大家好, 我终于找到了解决问题的一个非常棘手的解决方案。 我能够将用户保存到“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) {
}
});
正如你所看到的那样,如果查询返回该用户不在列表中,并且如果用户在那里,我将draable设置为star off。
所以在那之后我就能解决这个问题。 在我的查询之外,我创建了以下检查:
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();
}
}
});
在上面的代码中,我得到了按钮背景,并将其与我的drawable文件夹中存在的图像进行比较,并关闭了星标。 如果like按钮与star_off一起,它将设置类似,并将用户添加到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) {
}
});
}
});