Android仿淘寶商品詳情頁效果
本文實(shí)例為大家分享了Android仿淘寶商品詳情頁的具體代碼,供大家參考,具體內(nèi)容如下
Demo地址:先上效果圖

效果就是上面圖片的效果 接下來看看如何實(shí)現(xiàn)
首先我們來看下布局文件
<LinearLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="72dp"
android:paddingTop="24dp"
android:background="#00FFFFFF"
android:orientation="horizontal">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:src="@drawable/back"
/>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<ImageView
android:id="@+id/icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/aa"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
/>
</LinearLayout>
這塊主要是設(shè)置剛進(jìn)入頁面時(shí)的透明頭部 主要組成部分有返回鍵 和頭部的方形小圖片 還有分享按鈕 以及你想附加的標(biāo)題功能 默認(rèn)進(jìn)入是透明的只顯示返回按鈕
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioGroup
android:id="@+id/radioGroup"
android:background="#00FFFFFF"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="48dp">
<RadioButton
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:button="@null"
android:textColor="#00000000"
android:gravity="center"
android:text="寶貝"/>
<RadioButton
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:button="@null"
android:textColor="#00000000"
android:gravity="center"
android:text="評(píng)價(jià)"/>
<RadioButton
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:button="@null"
android:textColor="#00000000"
android:gravity="center"
android:text="詳情"/>
<RadioButton
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:button="@null"
android:textColor="#00000000"
android:text="推薦"/>
</RadioGroup>
<View
android:id="@+id/layer"
android:layout_width="match_parent"
android:background="#00FFFFFF"
android:layout_height="48dp"/>
</FrameLayout>
這部分主要是我們的標(biāo)簽選項(xiàng)卡 我這邊采用的是RadioGroup+radioButton實(shí)現(xiàn)的 類似于淘寶的商品、評(píng)價(jià)、詳情等標(biāo)簽
這樣我們的頁面布局頭部就完成了 下面我們來看下具體組成內(nèi)容
<com.text.lg.ideascrollview.IdeaScrollView
android:id="@+id/ideaScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.text.lg.ideascrollview.IdeaViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:background="@drawable/aa"
android:layout_height="wrap_content"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/one"/>
</LinearLayout>
<LinearLayout
android:id="@+id/two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/two"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/three"/>
</LinearLayout>
<ImageView
android:id="@+id/three"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/four"/>
<LinearLayout
android:id="@+id/four"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/five"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/six"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/six"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/six"/>
</LinearLayout>
</LinearLayout>
</com.text.lg.ideascrollview.IdeaScrollView>
這部分就是我們的具體頁面內(nèi)容 可以看到我們的詳情頁面數(shù)據(jù)使用自定義的一個(gè)Scrollview來包裹的 其中分為4塊 我們布局里面寫的很清楚 分別對(duì)應(yīng)著詳情頁中的四個(gè)模塊 當(dāng)然 我這里面只是用圖片來代替內(nèi)容了 具體內(nèi)容可自己填充
下面來看下我們具體實(shí)現(xiàn)代碼
StatusBarCompat.translucentStatusBar(this);
我這邊是采用的第三方的沉浸式透明狀態(tài)欄 你們可以自行替換
dependencies {
compile ('com.github.niorgai:StatusBarCompat:2.1.4', {
exclude group: 'com.android.support'
})
}
這個(gè)是我沉浸式狀態(tài)欄的依賴 感興趣的可以了解一下
Rect rectangle= new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(rectangle);
ideaScrollView.setViewPager(viewPager,getMeasureHeight(headerParent)-rectangle.top);
icon.setImageAlpha(0);
radioGroup.setAlpha(0);
radioGroup.check(radioGroup.getChildAt(0).getId());
上面是獲取狀態(tài)欄的高度并且使用自定義scrollview綁定banner圖片 并獲取圖片高度
以及初始化我們頭部部分控件的透明度 和默認(rèn)選擇第一個(gè)標(biāo)簽
View one = findViewById(R.id.one); View two = findViewById(R.id.two); View four = findViewById(R.id.four); View three = findViewById(R.id.three); ArrayList<Integer> araryDistance = new ArrayList<>(); araryDistance.add(0); araryDistance.add(getMeasureHeight(one)-getMeasureHeight(headerParent)); araryDistance.add(getMeasureHeight(one)+getMeasureHeight(two)-getMeasureHeight(headerParent)); araryDistance.add(getMeasureHeight(one)+getMeasureHeight(two)+getMeasureHeight(three)-getMeasureHeight(headerParent)); ideaScrollView.setArrayDistance(araryDistance);
這塊是我們獲取到我們的四個(gè)模塊的高度 并把高度存到集合中 傳入到我們自定義的scrollview中
private void scrollToPosition(int position){
scrollTo(0,arrayDistance.get(position));
}
scrollview通過傳過來的高度進(jìn)行定位滑動(dòng) 意思就是點(diǎn)擊我們的標(biāo)題選項(xiàng)滑動(dòng)到相應(yīng)的位置
public int getMeasureHeight(View view){
int width = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
int height = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
view.measure(width, height);
return view.getMeasuredHeight();
}
這個(gè)是獲取控件高度的方法
ideaScrollView.setOnScrollChangedColorListener(new IdeaScrollView.OnScrollChangedColorListener() {
@Override
public void onChanged(float percentage) {
int color = getAlphaColor(percentage>0.9f?1.0f:percentage);
header.setBackgroundDrawable(new ColorDrawable(color));
radioGroup.setBackgroundDrawable(new ColorDrawable(color));
icon.setImageAlpha((int) ((percentage>0.9f?1.0f:percentage)*255));
radioGroup.setAlpha((percentage>0.9f?1.0f:percentage)*255);
setRadioButtonTextColor(percentage);
}
@Override
public void onChangedFirstColor(float percentage) {
}
@Override
public void onChangedSecondColor(float percentage) {
}
});
這個(gè)監(jiān)聽方法是監(jiān)測(cè)我們滑動(dòng)的距離 來改變我們標(biāo)題的顏色 從透明慢慢滑動(dòng)進(jìn)行顏色漸變 以及設(shè)置我們頭部控件的顏色 和展示我們的標(biāo)題選項(xiàng)卡
public int getAlphaColor(float f){
return Color.argb((int) (f*255),0x09,0xc1,0xf4);
}
public int getLayerAlphaColor(float f){
return Color.argb((int) (f*255),0x09,0xc1,0xf4);
}
public int getRadioCheckedAlphaColor(float f){
return Color.argb((int) (f*255),0x44,0x44,0x44);
}
public int getRadioAlphaColor(float f){
return Color.argb((int) (f*255),0xFF,0xFF,0xFF);
}
可以根據(jù)這塊來改變我們頭部以及標(biāo)題的顏色 根據(jù)傳入的值來進(jìn)行顏色漸變
ideaScrollView.setOnSelectedIndicateChangedListener(new IdeaScrollView.OnSelectedIndicateChangedListener() {
@Override
public void onSelectedChanged(int position) {
isNeedScrollTo = false;
radioGroup.check(radioGroup.getChildAt(position).getId());
isNeedScrollTo = true;
}
});
radioGroup.setOnCheckedChangeListener(radioGroupListener);
private RadioGroup.OnCheckedChangeListener radioGroupListener =new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
for(int i=0;i<radioGroup.getChildCount();i++){
RadioButton radioButton = (RadioButton) radioGroup.getChildAt(i);
radioButton.setTextColor(radioButton.isChecked()?getRadioCheckedAlphaColor(currentPercentage):getRadioAlphaColor(currentPercentage));
if(radioButton.isChecked()&&isNeedScrollTo){
ideaScrollView.setPosition(i);
}
}
}
};
根據(jù)這兩個(gè)監(jiān)聽方法來改變我們標(biāo)題的選中tab 滑動(dòng)到不同的位置選中對(duì)應(yīng)的Tab并改變顏色 具體實(shí)現(xiàn)方法看自定義Scrollview
根據(jù)限定距離(Banner)計(jì)算百分比偏移量,實(shí)現(xiàn)顏色漸變、透明度漸變(淘寶商品詳情頁有二次顏色漸變)
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (viewPager != null && t != oldt) {
viewPager.setTranslationY(t/2);
}
if(viewPager!=null&&t<=point.x-headerHeight&&getOnScrollChangedColorListener()!=null){
getOnScrollChangedColorListener().onChanged(Math.abs(t)/Float.valueOf(point.x-headerHeight));
if(t<=(point.x-headerHeight)/2){
getOnScrollChangedColorListener().onChangedFirstColor(t/(point.x-headerHeight)/2);
}else{
getOnScrollChangedColorListener().onChangedSecondColor((t-(point.x-headerHeight)/2)/(point.x-headerHeight)/2);
}
}
int currentPosition = getCurrentPosition(t,arrayDistance);
if(currentPosition!=position&&getOnSelectedIndicateChangedListener()!=null){
getOnSelectedIndicateChangedListener().onSelectedChanged(currentPosition);
}
this.position = currentPosition;
}
private int getCurrentPosition(int t, ArrayList<Integer> arrayDistance) {
int index = 0;
for (int i=0;i<arrayDistance.size();i++){
if(i==arrayDistance.size()-1){
index = i;
}else {
if(t>=arrayDistance.get(i)&&t<arrayDistance.get(i+1)){
index = i;
break;
}
}
}
return index;
}
下面是自定義Scrollview的全部代碼
package com.text.lg.ideascrollview;
import android.content.Context;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.WindowManager;
import android.widget.ScrollView;
import java.util.ArrayList;
public class IdeaScrollView extends ScrollView {
private final Point point;
private IdeaViewPager viewPager;
private int position = 0;
ArrayList<Integer> arrayDistance = new ArrayList<>();
private int headerHeight;
public IdeaScrollView(Context context) {
this(context,null,0);
}
public IdeaScrollView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public IdeaScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
point = new Point();
windowManager.getDefaultDisplay().getSize(point);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (viewPager != null && t != oldt) {
viewPager.setTranslationY(t/2);
}
if(viewPager!=null&&t<=point.x-headerHeight&&getOnScrollChangedColorListener()!=null){
getOnScrollChangedColorListener().onChanged(Math.abs(t)/Float.valueOf(point.x-headerHeight));
if(t<=(point.x-headerHeight)/2){
getOnScrollChangedColorListener().onChangedFirstColor(t/(point.x-headerHeight)/2);
}else{
getOnScrollChangedColorListener().onChangedSecondColor((t-(point.x-headerHeight)/2)/(point.x-headerHeight)/2);
}
}
int currentPosition = getCurrentPosition(t,arrayDistance);
if(currentPosition!=position&&getOnSelectedIndicateChangedListener()!=null){
getOnSelectedIndicateChangedListener().onSelectedChanged(currentPosition);
}
this.position = currentPosition;
}
private int getCurrentPosition(int t, ArrayList<Integer> arrayDistance) {
int index = 0;
for (int i=0;i<arrayDistance.size();i++){
if(i==arrayDistance.size()-1){
index = i;
}else {
if(t>=arrayDistance.get(i)&&t<arrayDistance.get(i+1)){
index = i;
break;
}
}
}
return index;
}
private void scrollToPosition() {
scrollToPosition(position);
}
private void scrollToPosition(int position){
scrollTo(0,arrayDistance.get(position));
}
public void setViewPager(IdeaViewPager viewPager,int headerHeight){
this.viewPager = viewPager;
this.headerHeight = headerHeight;
}
public interface OnScrollChangedColorListener{
void onChanged(float percentage);
void onChangedFirstColor(float percentage);
void onChangedSecondColor(float percentage);
}
public interface OnSelectedIndicateChangedListener{
void onSelectedChanged(int position);
}
private OnSelectedIndicateChangedListener onSelectedIndicateChangedListener;
private OnScrollChangedColorListener onScrollChangedColorListener;
public OnScrollChangedColorListener getOnScrollChangedColorListener() {
return onScrollChangedColorListener;
}
public void setOnScrollChangedColorListener(OnScrollChangedColorListener onScrollChangedColorListener) {
this.onScrollChangedColorListener = onScrollChangedColorListener;
}
public IdeaViewPager getViewPager() {
return viewPager;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
scrollToPosition();
}
public ArrayList<Integer> getArrayDistance() {
return arrayDistance;
}
public void setArrayDistance(ArrayList<Integer> arrayDistance) {
this.arrayDistance = arrayDistance;
}
public OnSelectedIndicateChangedListener getOnSelectedIndicateChangedListener() {
return onSelectedIndicateChangedListener;
}
public void setOnSelectedIndicateChangedListener(OnSelectedIndicateChangedListener onSelectedIndicateChangedListener) {
this.onSelectedIndicateChangedListener = onSelectedIndicateChangedListener;
}
}
以上代碼就實(shí)現(xiàn)了文中效果圖樣式。
本文借鑒了大佬博客內(nèi)容 Android仿淘寶商品詳情頁
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android自定View實(shí)現(xiàn)滑動(dòng)驗(yàn)證效果的代碼
這篇文章主要介紹了Android自定View實(shí)現(xiàn)滑動(dòng)驗(yàn)證效果,代碼分為自定義屬性代碼和自定義view代碼及使用方法,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12
Android音視頻開發(fā)之VideoView使用指南
VideoView組件內(nèi)部同樣是使用MediaPlayer+SurfaceView的形式控制MediaPlayer對(duì)視頻文件進(jìn)行播放,本文就來詳細(xì)講講它的使用方法,需要的可以參考一下2022-04-04
Android自動(dòng)化如何獲取視圖元素屬性(最新推薦)
在做Android自動(dòng)化時(shí)候,我們需要知道視圖有哪些元素,元素都有哪些屬性,獲取到屬性我們才能獲取到元素從而做自動(dòng)化控制,所以做Android自動(dòng)化獲取元素屬性是必要的第一步,這篇文章主要介紹了Android自動(dòng)化如何獲取視圖元素屬性(最新推薦),需要的朋友可以參考下2024-07-07
Android編程實(shí)現(xiàn)定時(shí)發(fā)短信功能示例
這篇文章主要介紹了Android編程實(shí)現(xiàn)定時(shí)發(fā)短信功能,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android定時(shí)發(fā)送短信功能的相關(guān)原理、實(shí)現(xiàn)方法與注意事項(xiàng),需要的朋友可以參考下2017-09-09
android使用Rxjava實(shí)現(xiàn)倒計(jì)時(shí)功能
這篇文章主要為大家詳細(xì)介紹了android使用Rxjava實(shí)現(xiàn)倒計(jì)時(shí)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
Android Studio 自定義Debug變量視圖的方法
這篇文章主要介紹了Android Studio 自定義Debug變量視圖的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07
Android仿微信朋友圈點(diǎn)贊和評(píng)論功能
這篇文章主要為大家詳細(xì)介紹了Android仿微信朋友圈點(diǎn)贊和評(píng)論功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06

