diff options
author | Roman Romanov <rromanov@65gb.net> | 2016-09-19 15:40:06 +0300 |
---|---|---|
committer | Roman Romanov <rromanov@65gb.net> | 2016-10-03 13:31:58 +0300 |
commit | 4571b089fc119bd28562ed15151ded4874884b48 (patch) | |
tree | 2275d50d64da6d43770a956601af2b5f3cdfcf4c /android | |
parent | c7761277083408d712b59d8395bec00b3836c464 (diff) |
[android] added review activity
Diffstat (limited to 'android')
10 files changed, 395 insertions, 13 deletions
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 92ed583af1..95c0151f2b 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -307,6 +307,15 @@ android:value="com.mapswithme.maps.MwmActivity"/> </activity> + <activity + android:name="com.mapswithme.maps.review.ReviewActivity" + android:parentActivityName="com.mapswithme.maps.MwmActivity"> + <!-- The meta-data element is needed for versions lower than 4.1 --> + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value="com.mapswithme.maps.MwmActivity"/> + </activity> + <!-- facebook --> <activity android:name="com.facebook.FacebookActivity" diff --git a/android/res/layout/fragment_review.xml b/android/res/layout/fragment_review.xml new file mode 100644 index 0000000000..a0a0e70860 --- /dev/null +++ b/android/res/layout/fragment_review.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="@dimen/margin_placepage_rating" + android:paddingBottom="@dimen/margin_base" + android:paddingLeft="@dimen/margin_base" + android:paddingRight="@dimen/margin_base" + android:background="@color/bg_placepage_rating"> + + <TextView + android:id="@+id/tv__place_hotel_rating" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/MwmTextAppearance.Body1" + android:textColor="@color/text_placepage_rating" + tools:text="Rating: 8.7 (Excellent)"/> + + <TextView + android:id="@+id/tv__place_hotel_rating_base" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/margin_half" + android:textAppearance="@style/MwmTextAppearance.Body3" + tools:text="Based on 848 hotel reviews"/> + </LinearLayout> + + <android.support.v7.widget.RecyclerView + android:id="@+id/rv__review" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:listitem="@layout/item_comment"/> +</LinearLayout>
\ No newline at end of file diff --git a/android/res/layout/item_more_button.xml b/android/res/layout/item_more_button.xml new file mode 100644 index 0000000000..e4e113952d --- /dev/null +++ b/android/res/layout/item_more_button.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<TextView + xmlns:android="http://schemas.android.com/apk/res/android" + style="@style/PlacePageMetadataText.Button" + android:height="@dimen/height_block_base" + android:background="?clickableBackground" + android:gravity="center" + android:text="@string/placepage_more_reviews_button"/>
\ No newline at end of file diff --git a/android/res/layout/place_page_hotel_rating.xml b/android/res/layout/place_page_hotel_rating.xml index 218e5b1ae0..2b47b9da2a 100644 --- a/android/res/layout/place_page_hotel_rating.xml +++ b/android/res/layout/place_page_hotel_rating.xml @@ -42,11 +42,15 @@ android:numColumns="1" tools:listitem="@layout/item_comment"/> + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:layout_marginLeft="@dimen/margin_base" + android:layout_marginRight="@dimen/margin_base" + android:background="?dividerHorizontal"/> <TextView android:id="@+id/tv__place_hotel_reviews_more" style="@style/PlacePageMetadataText.Button" - android:layout_marginLeft="@dimen/margin_base" - android:layout_marginRight="@dimen/margin_base" android:height="@dimen/height_block_base" android:background="?clickableBackground" android:gravity="center" diff --git a/android/src/com/mapswithme/maps/review/ReviewActivity.java b/android/src/com/mapswithme/maps/review/ReviewActivity.java new file mode 100644 index 0000000000..a34e663eef --- /dev/null +++ b/android/src/com/mapswithme/maps/review/ReviewActivity.java @@ -0,0 +1,64 @@ +package com.mapswithme.maps.review; + +import com.mapswithme.maps.R; +import com.mapswithme.maps.base.BaseMwmFragmentActivity; +import com.mapswithme.maps.widget.placepage.SponsoredHotel; +import com.mapswithme.util.UiUtils; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v7.widget.Toolbar; + +import java.util.ArrayList; + +public class ReviewActivity extends BaseMwmFragmentActivity { + static final String EXTRA_REVIEWS = "review_items"; + static final String EXTRA_TITLE = "review_title"; + static final String EXTRA_RATING = "review_rating"; + static final String EXTRA_RATING_BASE = "review_rating_base"; + static final String EXTRA_RATING_URL = "review_rating_url"; + + public static void start(Context context, ArrayList<SponsoredHotel.Review> items, String title, + String rating, int ratingBase, String url) + { + final Intent i = new Intent(context, ReviewActivity.class); + i.putParcelableArrayListExtra(EXTRA_REVIEWS, items); + i.putExtra(EXTRA_TITLE, title); + i.putExtra(EXTRA_RATING, rating); + i.putExtra(EXTRA_RATING_BASE, ratingBase); + i.putExtra(EXTRA_RATING_URL, url); + context.startActivity(i); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + String title = ""; + Bundle bundle = getIntent().getExtras(); + if (bundle != null) { + title = bundle.getString(EXTRA_TITLE); + } + Toolbar toolbar = getToolbar(); + toolbar.setTitle(title); + UiUtils.showHomeUpButton(toolbar); + displayToolbarAsActionBar(); + } + + @Override + protected Class<? extends Fragment> getFragmentClass() { + return ReviewFragment.class; + } + + @Override + protected int getContentLayoutResId() { + return R.layout.activity_fragment_and_toolbar; + } + + @Override + protected int getFragmentContentResId() { + return R.id.fragment_container; + } +} diff --git a/android/src/com/mapswithme/maps/review/ReviewAdapter.java b/android/src/com/mapswithme/maps/review/ReviewAdapter.java new file mode 100644 index 0000000000..f31940aae0 --- /dev/null +++ b/android/src/com/mapswithme/maps/review/ReviewAdapter.java @@ -0,0 +1,148 @@ +package com.mapswithme.maps.review; + +import com.mapswithme.maps.R; +import com.mapswithme.maps.widget.placepage.SponsoredHotel; +import com.mapswithme.maps.widget.recycler.RecyclerClickListener; +import com.mapswithme.util.UiUtils; + +import android.support.annotation.CallSuper; +import android.support.v7.widget.RecyclerView; +import android.text.TextUtils; +import android.text.format.DateFormat; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.Date; +import java.util.Locale; + +public class ReviewAdapter extends RecyclerView.Adapter<ReviewAdapter.BaseViewHolder> { + private static final int MAX_COUNT = 15; + private static final int VIEW_TYPE_REVIEW = 0; + private static final int VIEW_TYPE_MORE = 1; + + private final ArrayList<SponsoredHotel.Review> mItems; + private final RecyclerClickListener mListener; + + public ReviewAdapter(ArrayList<SponsoredHotel.Review> images, RecyclerClickListener listener) { + mItems = images; + mListener = listener; + } + + @Override + public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_REVIEW) { + return new ReviewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_comment, parent, false), mListener); + } + + return new MoreHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_more_button, parent, false), mListener); + } + + @Override + public void onBindViewHolder(BaseViewHolder holder, int position) { + if (position < mItems.size()) { + holder.bind(mItems.get(position), position); + } else { + holder.bind(null, position); + } + } + + @Override + public int getItemCount() { + if (mItems == null) { + return 0; + } + if (mItems.size() > MAX_COUNT) { + return MAX_COUNT + 1; + } + return mItems.size() + 1; + } + + @Override + public int getItemViewType(int position) { + if (position == mItems.size()) { + return VIEW_TYPE_MORE; + } + + return VIEW_TYPE_REVIEW; + } + + static abstract class BaseViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + private final RecyclerClickListener mListener; + private int mPosition; + + public BaseViewHolder(View itemView, RecyclerClickListener listener) { + super(itemView); + mListener = listener; + } + + @Override + public void onClick(View v) { + if (mListener != null) { + mListener.onItemClick(v, mPosition); + } + } + + @CallSuper + public void bind(SponsoredHotel.Review item, int position) { + mPosition = position; + } + } + + static class ReviewHolder extends BaseViewHolder { + final View mDivider; + final TextView mUserName; + final TextView mCommentDate; + final TextView mRating; + final View mPositiveReview; + final TextView mTvPositiveReview; + final View mNegativeReview; + final TextView mTvNegativeReview; + + public ReviewHolder(View itemView, RecyclerClickListener listener) { + super(itemView, listener); + mDivider = itemView.findViewById(R.id.v__divider); + mUserName = (TextView) itemView.findViewById(R.id.tv__user_name); + mCommentDate = (TextView) itemView.findViewById(R.id.tv__comment_date); + mRating = (TextView) itemView.findViewById(R.id.tv__user_rating); + mPositiveReview = itemView.findViewById(R.id.ll__positive_review); + mTvPositiveReview = (TextView) itemView.findViewById(R.id.tv__positive_review); + mNegativeReview = itemView.findViewById(R.id.ll__negative_review); + mTvNegativeReview = (TextView) itemView.findViewById(R.id.tv__negative_review); + } + + @Override + public void bind(SponsoredHotel.Review item, int position) { + super.bind(item, position); + UiUtils.showIf(position > 0, mDivider); + mUserName.setText(item.getAuthor()); + Date date = new Date(item.getDate()); + mCommentDate.setText(DateFormat.getMediumDateFormat(mCommentDate.getContext()).format(date)); + mRating.setText(String.format(Locale.getDefault(), "%.1f", item.getRating())); + if (TextUtils.isEmpty(item.getReviewPositive())) { + UiUtils.hide(mPositiveReview); + } else { + UiUtils.show(mPositiveReview); + mTvPositiveReview.setText(item.getReviewPositive()); + } + if (TextUtils.isEmpty(item.getReviewNegative())) { + UiUtils.hide(mNegativeReview); + } else { + UiUtils.show(mNegativeReview); + mTvNegativeReview.setText(item.getReviewNegative()); + } + } + } + + static class MoreHolder extends BaseViewHolder { + + public MoreHolder(View itemView, RecyclerClickListener listener) { + super(itemView, listener); + itemView.setOnClickListener(this); + } + } +} diff --git a/android/src/com/mapswithme/maps/review/ReviewFragment.java b/android/src/com/mapswithme/maps/review/ReviewFragment.java new file mode 100644 index 0000000000..0a834c98fd --- /dev/null +++ b/android/src/com/mapswithme/maps/review/ReviewFragment.java @@ -0,0 +1,70 @@ +package com.mapswithme.maps.review; + +import com.mapswithme.maps.R; +import com.mapswithme.maps.base.BaseMwmFragment; +import com.mapswithme.maps.widget.placepage.SponsoredHotel; +import com.mapswithme.maps.widget.recycler.RecyclerClickListener; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.ArrayList; + +public class ReviewFragment extends BaseMwmFragment implements RecyclerClickListener { + private ArrayList<SponsoredHotel.Review> mItems; + private String mRating; + private int mRatingBase; + private String mUrl; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_review, container, false); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + readArguments(); + + RecyclerView rvGallery = (RecyclerView) view.findViewById(R.id.rv__review); + rvGallery.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + rvGallery.setAdapter(new ReviewAdapter(mItems, this)); + TextView hotelRating = (TextView) view.findViewById(R.id.tv__place_hotel_rating); + TextView hotelRatingBase = (TextView) view.findViewById(R.id.tv__place_hotel_rating_base); + hotelRating.setText(mRating); + hotelRatingBase.setText(getResources().getQuantityString(R.plurals.place_page_booking_rating_base, + mRatingBase, mRatingBase)); + } + + private void readArguments() + { + final Bundle arguments = getArguments(); + if (arguments == null) + return; + + mItems = arguments.getParcelableArrayList(ReviewActivity.EXTRA_REVIEWS); + mRating = arguments.getString(ReviewActivity.EXTRA_RATING); + mRatingBase = arguments.getInt(ReviewActivity.EXTRA_RATING_BASE); + mUrl = arguments.getString(ReviewActivity.EXTRA_RATING_URL); + } + + @Override + public void onItemClick(View v, int position) { + final Intent intent = new Intent(Intent.ACTION_VIEW); + String url = mUrl; + if (!url.startsWith("http://") && !url.startsWith("https://")) + url = "http://" + url; + intent.setData(Uri.parse(url)); + getContext().startActivity(intent); + } +} diff --git a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java index 1be90edc1e..008144c3d4 100644 --- a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java +++ b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java @@ -64,6 +64,7 @@ import com.mapswithme.maps.editor.data.TimeFormatUtils; import com.mapswithme.maps.editor.data.Timetable; import com.mapswithme.maps.gallery.GalleryActivity; import com.mapswithme.maps.location.LocationHelper; +import com.mapswithme.maps.review.ReviewActivity; import com.mapswithme.maps.routing.RoutingController; import com.mapswithme.maps.widget.ArrowView; import com.mapswithme.maps.widget.BaseShadowController; @@ -150,7 +151,6 @@ public class PlacePageView extends RelativeLayout private View mHotelReview; private TextView mHotelRating; private TextView mHotelRatingBase; - private View mHotelMoreReviews; // Animations private BaseShadowController mShadowController; @@ -331,8 +331,8 @@ public class PlacePageView extends RelativeLayout gvHotelReview.setAdapter(mReviewAdapter); mHotelRating = (TextView) findViewById(R.id.tv__place_hotel_rating); mHotelRatingBase = (TextView) findViewById(R.id.tv__place_hotel_rating_base); - mHotelMoreReviews = findViewById(R.id.tv__place_hotel_reviews_more); - mHotelMoreReviews.setOnClickListener(this); + View hotelMoreReviews = findViewById(R.id.tv__place_hotel_reviews_more); + hotelMoreReviews.setOnClickListener(this); mButtons = new PlacePageButtons(this, ppButtons, new PlacePageButtons.ItemListener() { @@ -524,12 +524,10 @@ public class PlacePageView extends RelativeLayout UiUtils.hide(mHotelReview); } else { UiUtils.show(mHotelReview); - mReviewAdapter.setItems(Arrays.asList(info.reviews)); + mReviewAdapter.setItems(new ArrayList<>(Arrays.asList(info.reviews))); mHotelRating.setText(mSponsoredHotel.rating); mHotelRatingBase.setText(getResources().getQuantityString(R.plurals.place_page_booking_rating_base, info.reviews.length, info.reviews.length)); - mHotelMoreReviews.setVisibility(info.reviews.length > ReviewAdapter.MAX_COUNT - ? VISIBLE : GONE); } } @@ -1086,7 +1084,8 @@ public class PlacePageView extends RelativeLayout mFacilitiesAdapter.setShowAll(true); break; case R.id.tv__place_hotel_reviews_more: -// TODO go to reviews activity + ReviewActivity.start(getContext(), mReviewAdapter.getItems(), mMapObject.getTitle(), + mSponsoredHotel.rating, mReviewAdapter.getItems().size(), mSponsoredHotel.urlBook); break; } } diff --git a/android/src/com/mapswithme/maps/widget/placepage/ReviewAdapter.java b/android/src/com/mapswithme/maps/widget/placepage/ReviewAdapter.java index b0b7014ed4..06eb0285df 100644 --- a/android/src/com/mapswithme/maps/widget/placepage/ReviewAdapter.java +++ b/android/src/com/mapswithme/maps/widget/placepage/ReviewAdapter.java @@ -13,13 +13,12 @@ import android.widget.TextView; import java.util.ArrayList; import java.util.Date; -import java.util.List; import java.util.Locale; public class ReviewAdapter extends BaseAdapter { public static final int MAX_COUNT = 3; - private List<SponsoredHotel.Review> items = new ArrayList<>(); + private ArrayList<SponsoredHotel.Review> items = new ArrayList<>(); @Override public int getCount() { @@ -57,11 +56,15 @@ public class ReviewAdapter extends BaseAdapter { } public void setItems( - List<SponsoredHotel.Review> items) { + ArrayList<SponsoredHotel.Review> items) { this.items = items; notifyDataSetChanged(); } + public ArrayList<SponsoredHotel.Review> getItems() { + return items; + } + private static class ViewHolder { final View mDivider; final TextView mUserName; diff --git a/android/src/com/mapswithme/maps/widget/placepage/SponsoredHotel.java b/android/src/com/mapswithme/maps/widget/placepage/SponsoredHotel.java index 1a622c586f..2792bf4a06 100644 --- a/android/src/com/mapswithme/maps/widget/placepage/SponsoredHotel.java +++ b/android/src/com/mapswithme/maps/widget/placepage/SponsoredHotel.java @@ -1,6 +1,8 @@ package com.mapswithme.maps.widget.placepage; import android.support.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; import android.support.annotation.UiThread; import android.text.TextUtils; @@ -81,7 +83,7 @@ public final class SponsoredHotel } } - public static class Review { + public static class Review implements Parcelable { private final String mReviewPositive; private final String mReviewNegative; private final String mAuthor; @@ -99,6 +101,42 @@ public final class SponsoredHotel mDate = date; } + protected Review(Parcel in) { + mReviewPositive = in.readString(); + mReviewNegative = in.readString(); + mAuthor = in.readString(); + mAuthorAvatar = in.readString(); + mRating = in.readFloat(); + mDate = in.readLong(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mReviewPositive); + dest.writeString(mReviewNegative); + dest.writeString(mAuthor); + dest.writeString(mAuthorAvatar); + dest.writeFloat(mRating); + dest.writeLong(mDate); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator<Review> CREATOR = new Creator<Review>() { + @Override + public Review createFromParcel(Parcel in) { + return new Review(in); + } + + @Override + public Review[] newArray(int size) { + return new Review[size]; + } + }; + public String getReviewPositive() { return mReviewPositive; } |