0

バックエンドレス サポート フォーラムから来ました。「このサポート フォーラムは、バックエンドレス関連の問題専用です。API およびバックエンド サービス以外の一般的な問題は、サポートの対象外です。stackoverflow.com や Android フォーラムへの投稿を検討してください。」マーク・ピラー。

だから私はここに私の問題を投稿しています。バックエンドレス サポート フォーラムで、関係を保存および取得するための貴重な助けを得ましたが、今は [いいね] ボタンで別の問題に直面しています。私は 3 つのボタンがあるソーシャル アプリに取り組んでいます: Like Comment Share。バックエンドレス サポート スレッドのリンク: http://support.backendless.com/topic/some-questions-regarding-data-loading-in-recyclerview-android 今のところ、いいねボタンを機能させようとしていますが、直面しています次の問題:

次のコードと私が添付したスクリーンショットを見ると、ハートのようなボタンが満たされていないことがわかります。これは、その投稿に対して「いいね」を押していないことを意味します。そして、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);

}

しかし問題は、空のハートをクリックしても機能しないことです。クリックが機能するかどうかを確認するためにトーストを作成しようとしましたが、トーストが表示されません。

しかし、気に入ったアイテム(ハートアイコンが塗りつぶされている)をクリックすると、クリックを聞くかどうかを確認するために置いたトーストが表示されます....

アプリをデバッグしようとしましたが、デバッグ ウィンドウに何も表示されません...すべて正常に見えますが、コードの問題を特定できません。私のアダプタークラスは次のとおりです。

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();

}

そして、ここに私のフィードクラスがあります:

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 で、次のようにドローアブルをチェックしています。

//***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 の 2 つの部分を見ると、ユーザーが以前に投稿を気に入った場合にのみ、ボタンの 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);

}

編集:

コードから、2 つの 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
             }
          }
    
      });
    
于 2016-04-10T17:52:17.700 に答える
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) {

        }

    });

ご覧のとおり、クエリがユーザーがリストにないことを返す場合はスターをオフにし、ユーザーがリストにある場合はオンにして、ドローアブルを設定します。

その後、問題を解決できた方法を次に示します。クエリの外で、次のチェックを作成しました。

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 リストにユーザーを追加します。それ以外の場合は、トーストを表示します: 「このアイテムは既に気に入りました」

私はこの問題に多くの時間を費やしてきたので、それが他の人を助け、時間を節約できることを願っています.

よろしく


古い答え:

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 に答える