android自定义视图之类似淘宝商品详情

编程入门 行业动态 更新时间:2024-10-24 05:23:31

android<a href=https://www.elefans.com/category/jswz/34/1771438.html style=自定义视图之类似淘宝商品详情"/>

android自定义视图之类似淘宝商品详情

公司项目需求,需要一个类似淘宝详情一样的页面,但又有所不同,于是自己写了一个。本文只是提供一种思路,控件的普适性还不够,希望读者能自行修改。


老规矩,先上一个项目原图吧:



本文只是上图右边部分效果。demo也只有右边部分。不过这个控件的代码是一样的。

直接贴代码

TwoPageLayout.java:

/*** Created by paulz on 2016/9/21.*/
public class TwoPageLayout extends ViewGroup {Context context;View pageOne;View pageTwo;private int mTouchSlop;private int mPageChangeLimit;private int currentPage;private boolean isIntercept;OnPageChangeListener mOnPageChangeListener;public OverScroller scroller;public TwoPageLayout(Context context) {super(context);init(context);}public TwoPageLayout(Context context, AttributeSet attrs) {super(context, attrs);init(context);}public TwoPageLayout(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context);}private void init(Context context){this.context=context;final ViewConfiguration vc = ViewConfiguration.get(context);mTouchSlop=vc.getScaledTouchSlop();//滑动翻页的临界值mPageChangeLimit=150;scroller=new OverScroller(getContext());}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {switch (ev.getAction()){case MotionEvent.ACTION_DOWN:downX=ev.getX();downY=ev.getY();isIntercept=touchChildToTop();break;case MotionEvent.ACTION_MOVE:if(!isIntercept)return false;if(Math.abs(downY-ev.getY())>mTouchSlop){//滑动开始if(currentPage==1&&downY-ev.getY()<0){isScrolling=true;return true;}else if(currentPage==0&&downY-ev.getY()>0){isScrolling=true;return true;}}break;case MotionEvent.ACTION_UP:isScrolling=false;break;case MotionEvent.ACTION_CANCEL:isScrolling=false;break;}return super.onInterceptTouchEvent(ev);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {measureChildren(widthMeasureSpec,heightMeasureSpec);super.onMeasure(widthMeasureSpec, heightMeasureSpec);if(pageOne==null){pageOne=getChildAt(0);}if(pageTwo==null){pageTwo=getChildAt(1);}}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {if (pageOne!=null&&pageOne.getVisibility() != GONE) {pageOne.layout(0+getPaddingLeft(), 0+getPaddingTop(), getWidth()-getPaddingRight(), getHeight()-getPaddingBottom());}if (pageTwo!=null&&pageTwo.getVisibility() != GONE) {pageTwo.layout(0+getPaddingLeft(), getHeight(), getWidth()-getPaddingRight(), getHeight()+getHeight()-getPaddingBottom());}}private float downX;private float downY;private boolean isScrolling;@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()){case MotionEvent.ACTION_DOWN:downX=event.getX();downY=event.getY();isIntercept=touchChildToTop();break;case MotionEvent.ACTION_MOVE:if(currentPage==1&&downY-event.getY()<0){isScrolling=true;}else if(currentPage==0&&downY-event.getY()>0){isScrolling=true;}else {isScrolling=false;}if(currentPage==1&&!isIntercept){isScrolling=false;}if(isScrolling){if(currentPage==0&&downY-event.getY()>0){//整体向上偏移,翻到下一页scrollTo(0,(int)(downY-event.getY()));}else if(currentPage==1&&downY-event.getY()<0){//翻到上一页scrollTo(0,getHeight()+(int)(downY-event.getY()));}else {return false;}}else {return false;}break;case MotionEvent.ACTION_UP:if(isScrolling){if(currentPage==0){if((downY-event.getY()>mPageChangeLimit)){scroller.startScroll(0,getScrollY(),0,getHeight()-getScrollY(),500);invalidate();
//                            scrollTo(0,getHeight());currentPage=1;if(mOnPageChangeListener!=null){mOnPageChangeListener.onPageChanged(currentPage,pageTwo,true);}}else {scroller.startScroll(0,getScrollY(),0,-getScrollY(),300);invalidate();
//                            scrollTo(0,0);}}else {if(Math.abs(downY-event.getY())>mPageChangeLimit){scroller.startScroll(0,getScrollY(),0,-getScrollY(),500);invalidate();if(mOnPageChangeListener!=null){mOnPageChangeListener.onPageChanged(currentPage,pageOne,true);}currentPage=0;}else {scroller.startScroll(0,getScrollY(),0,pageOne.getHeight()-getScrollY(),300);invalidate();
//                            scrollTo(0,pageOne.getHeight());}}isScrolling=false;}isIntercept=false;break;case MotionEvent.ACTION_CANCEL:isScrolling=false;scrollTo(0,0);isIntercept=false;break;}return true;}private WebView childOne;private ListView childTwo;private int curTouchChild;public void setScrollerChildren(WebView childOne, ListView childTwo){this.childOne=childOne;this.childTwo=childTwo;curTouchChild=0;}public void changeCurScrollerChild(int i){curTouchChild=i;}//实现第二页中包含可滑动控件时是否滑到顶部//从而决定本控件是否处理touch事件。private boolean touchChildToTop(){if(curTouchChild==0&&childOne!=null&&childOne.getScrollY()<=0){return true;}else if(curTouchChild==1&&childTwo!=null&&childTwo.getScrollY()<=0&&childTwo.getFirstVisiblePosition()==0){return true;}else {return false;}}@Overridepublic void computeScroll() {if(scrollerputeScrollOffset()){scrollTo(0,scroller.getCurrY());postInvalidate();}}public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener){mOnPageChangeListener=onPageChangeListener;}public interface OnPageChangeListener{public void onPageChanged(int page, View currentView,boolean bySelf);}}


MainActivity.java:

public class MainActivity extends AppCompatActivity {TwoPageLayout mLayout;WebView mWebView;RadioGroup mTabs;ListView mListview;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}private List<Map<String ,String>> getListData(){List<Map<String ,String>> data=new ArrayList<>();Random r=new Random(100);for(int i=0;i<20;i++){Map<String,String> map=new HashMap<>();map.put("key_text", "第二页第二选项卡 listview---item+"+i);map.put("key_text2", "呵呵 listview---item+"+i);data.add(map);}return data;}private void initView() {mLayout=(TwoPageLayout)findViewById(R.id.main_content);mWebView=(WebView)findViewById(R.id.web_view);mTabs=(RadioGroup)findViewById(R.id.radio_group);mListview=(ListView)findViewById(R.id.lv);initWebView();mWebView.loadUrl("");//设置滑动会冲突的视图进去mLayout.setScrollerChildren(mWebView,mListview);//第二页切换标签mTabs.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(RadioGroup group, int checkedId) {switch (checkedId){case R.id.rb_detail:mListview.setVisibility(View.GONE);mWebView.setVisibility(View.VISIBLE);mLayout.changeCurScrollerChild(0);break;case R.id.rb_comments:mWebView.setVisibility(View.GONE);mListview.setVisibility(View.VISIBLE);mLayout.changeCurScrollerChild(1);break;}}});mTabs.check(R.id.rb_detail);mListview.setAdapter(new SimpleAdapter(MainActivity.this,getListData(),R.layout.item_adapter,new String[]{"key_text","key_text2"},new int[]{R.id.text1,R.id.text2}));//监听切换到那一页了mLayout.setOnPageChangeListener(new TwoPageLayout.OnPageChangeListener() {@Overridepublic void onPageChanged(int page, View currentView, boolean bySelf) {Toast.makeText(getApplicationContext(),"当前页码:"+page+",是否自己改变:"+bySelf,Toast.LENGTH_LONG).show();if(page==1){
//                    mWebView.loadUrl("");if(mTabs.getCheckedRadioButtonId()==R.id.rb_detail){mWebView.loadUrl("");}}}});}private void initWebView() {// LayoutParams lp=new// LayoutParams(LayoutParams.MATCH_PARENT,ScreenUtil.HEIGHT);// mWebView.setLayoutParams(lp);// contentInSV.addView(mWebView);WebSettings wSet = mWebView.getSettings();wSet.setDefaultTextEncodingName("UTF-8");wSet.setJavaScriptEnabled(true);mWebView.setVerticalScrollbarOverlay(true); // 指定的垂直滚动条有叠加样式wSet.setUseWideViewPort(true);// 设定支持viewportwSet.setLoadWithOverviewMode(true);wSet.setBuiltInZoomControls(false);wSet.setSupportZoom(false);
//        wSet.setDisplayZoomControls(false);mWebView.setWebViewClient(new WebViewClient() {@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {// TODO Auto-generated method stubview.loadUrl(url);return true;}@Overridepublic void onPageFinished(WebView view, String url) {// TODO Auto-generated method stubsuper.onPageFinished(view, url);}});}
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=""xmlns:tools=""android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.paulz.towpageview.MainActivity"><com.paulz.towpageview.TwoPageLayoutandroid:id="@+id/main_content"android:padding="10dp"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_weight="1"android:background="@android:color/white"android:orientation="vertical" ><!--<ScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent">--><LinearLayoutandroid:id="@+id/layout_page1"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextViewandroid:id="@+id/tv_good_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:layout_toLeftOf="@+id/tv_promote_tip"android:minLines="3"android:background="@android:color/white"android:padding="5dp"android:text="杀寇决客流量卡可拉伸的"android:textColor="@android:color/black"android:textSize="16sp" /><TextViewandroid:id="@+id/tv_good_sub_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="20px"android:text="卡萨丁卡机考老师的"android:textColor="@android:color/black"android:textSize="16sp"android:visibility="visible" /><LinearLayoutandroid:id="@+id/layout_price_before"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@android:color/white"android:orientation="horizontal"android:paddingTop="10dp" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="市场价:"android:textColor="@android:color/darker_gray"android:textSize="14sp" /><TextViewandroid:id="@+id/tv_price_before"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="5dp"android:text="¥118.00元"android:textColor="@android:color/darker_gray"android:textSize="14sp" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="@android:color/white"android:orientation="horizontal"android:paddingTop="10dp" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="会员价:"android:textColor="@android:color/darker_gray"android:textSize="14sp" /><TextViewandroid:id="@+id/tv_price"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="0.00"android:textStyle="bold"android:textColor="#f98816"android:textSize="16sp" /></LinearLayout><Viewandroid:layout_width="1dp"android:layout_height="400dp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:drawableLeft="@drawable/ic_pull_up"android:drawablePadding="10dp"android:layout_gravity="center_horizontal"android:text="上拉查看更多"android:textSize="18sp"android:gravity="center_vertical"android:textColor="@android:color/darker_gray"android:layout_marginTop="10px"/></LinearLayout><!--</ScrollView>--><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><RadioGroupandroid:id="@+id/radio_group"android:layout_width="match_parent"android:layout_margin="20dp"android:layout_height="45dp"android:layout_gravity="center_horizontal"android:orientation="horizontal"><RadioButtonandroid:id="@+id/rb_detail"android:layout_width="0dp"android:layout_weight="1"android:layout_height="match_parent"android:textColor="@color/btn_white_and_yellow"android:background="@drawable/rb_bg_goods_detail"android:checked="true"android:button="@null"android:gravity="center"android:text="图文详情"android:textSize="16sp"/><RadioButtonandroid:id="@+id/rb_comments"android:layout_width="0dp"android:layout_weight="1"android:layout_height="match_parent"android:textColor="@color/btn_white_and_yellow"android:background="@drawable/rb_bg_goods_detail"android:button="@null"android:gravity="center"android:text="商品评价"android:textSize="16sp"/></RadioGroup><WebViewandroid:id="@+id/web_view"android:layout_width="match_parent"android:layout_height="match_parent"android:visibility="visible" /><ListViewandroid:id="@+id/lv"android:layout_width="match_parent"android:layout_height="match_parent"android:divider="@null"android:visibility="gone"/></LinearLayout></com.paulz.towpageview.TwoPageLayout>
</RelativeLayout>

主要代码就这几部分。TowPageLayout这个布局的用法有点类似DrawerLayout,他只能拥有2个子视图,看字面意思也就是2页的布局嘛。主要需要注意的是,当第二页有可滑动控件的情况,需要对事件拦截。滑动的动画是通过OverScroller这个类进行辅助计算。当然要注意,OverScroller只是负责计算滑动过程中的坐标变化,并不会改变控件的滑动状态,需要通过重绘来实现位置的改变。


源码地址:

更多推荐

android自定义视图之类似淘宝商品详情

本文发布于:2024-02-12 03:32:25,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1685646.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自定义   淘宝   视图   类似   详情

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!