高仿360手机助手应用详情页和贝贝商品详情页的实现
来源:互联网 发布:淘宝微淘刷粉丝封号吗 编辑:程序博客网 时间:2024/04/30 01:37
最近在做电商app,ui设计了一个仿360手机助手详情页和贝贝商品详情页的效果。我也对比了几个电商类的app 此种详情页还是比较普遍的。本来感觉实现起来挺简单的,我打算的实现方式是使用scrollview嵌套recyclerview、webview、scrollview。但是一旦牵涉到滑动的嵌套就难免会发生嵌套之后滑动事件的冲突。这种实现的主要难点就是处理滑动事件的冲突问题。先看一下这个UI效果的效果图。
这是360手机助手应用详情页的效果图:
这个是贝贝商品详情页的效果图:
这个是我自己实现的效果图:
为了以后能更加快速的实现这种效果我自己重写了一套相应的控件,包括:recyclerview、scrollview、webview,把原来的对应 的原生的控件换成对应的我自定义的控件再设置几个属性即可完成相应的效果,并且可以灵活布局,并不仅限于上面的布局方式。先把这三个的自定义控件的实现代码贴上:
下面是recyclerview的代码实现:
public class NFRecyclerView extends RecyclerView { public ScrollView parentScrollView; public int HeaderId; public int ContentContainerId; private int lastScrollDelta = 0; private boolean flag = false; public NFRecyclerView(Context context) { super(context); setFocusable(false); } public NFRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); setFocusable(false); } public NFRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setFocusable(false); } public void resume() { overScrollBy(0, -lastScrollDelta, 0, getScrollY(), 0, getScrollRange(), 0, 0, true); lastScrollDelta = 0; } int mTop = 10; public void scrollTo(View targetView) { int oldScrollY = getScrollY(); int top = targetView.getTop() - mTop; int delatY = top - oldScrollY; lastScrollDelta = delatY; overScrollBy(0, delatY, 0, getScrollY(), 0, getScrollRange(), 0, 0, true); } private int getScrollRange() { int scrollRange = 0; if (getChildCount() > 0) { View child = getChildAt(0); scrollRange = Math.max(0, child.getHeight() - (getHeight())); } return scrollRange; } int currentY; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (parentScrollView == null) { return super.onInterceptTouchEvent(ev); } else { View parentchild = parentScrollView.getChildAt(0); int height2 = parentchild.getMeasuredHeight(); height2 = height2 - parentScrollView.getMeasuredHeight(); int scrollY2 = parentScrollView.getScrollY(); if (ev.getAction() == MotionEvent.ACTION_DOWN) { if (scrollY2 >= height2) { // 将父scrollview的滚动事件拦截 currentY = (int) ev.getY(); setParentScrollAble(false); } } else if (ev.getAction() == MotionEvent.ACTION_UP) { // 把滚动事件恢复给父Scrollview setParentScrollAble(true); } else if (ev.getAction() == MotionEvent.ACTION_MOVE) { } } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { if (parentScrollView != null) { if (ev.getAction() == MotionEvent.ACTION_MOVE) { int y = (int) ev.getY(); View parentchild = parentScrollView.getChildAt(0); int height2 = parentchild.getMeasuredHeight(); height2 = height2 - parentScrollView.getMeasuredHeight(); int scrollY2 = parentScrollView.getScrollY(); if (scrollY2 >= height2) { // 手指向下滑动 if (currentY < y) { boolean result = false; LayoutManager manager = getLayoutManager(); if (manager instanceof GridLayoutManager) { GridLayoutManager gm = (GridLayoutManager) manager; result = gm.findViewByPosition(gm.findFirstVisibleItemPosition()).getTop() == 0 && gm.findFirstVisibleItemPosition() == 0; } else if (manager instanceof LinearLayoutManager) { LinearLayoutManager lm = (LinearLayoutManager) manager; result = lm.findViewByPosition(lm.findFirstVisibleItemPosition()).getTop() == 0 && lm.findFirstVisibleItemPosition() == 0; } if (result) { // 如果向下滑动到头,就把滚动交给父Scrollview setParentScrollAble(true); return false; } else { setParentScrollAble(false); } } /*else if (currentY > y) { if (scrollY >= height) { // 如果向上滑动到头,就把滚动交给父Scrollview setParentScrollAble(true); return false; } else { setParentScrollAble(false); } }*/ currentY = y; } } /*else { setParentScrollAble(true); }*/ } return super.onTouchEvent(ev); } private void setParentScrollAble(boolean flag) { parentScrollView.requestDisallowInterceptTouchEvent(!flag); }}
webview的代码:
public class NFWebView extends WebView { public ScrollView parentScrollView; public int HeaderId; public int ContentContainerId; private int lastScrollDelta = 0; public NFWebView(Context context) { super(context); setFocusable(false); } public NFWebView(Context context, AttributeSet attrs) { super(context, attrs); setFocusable(false); } public NFWebView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setFocusable(false); } public void resume() { overScrollBy(0, -lastScrollDelta, 0, getScrollY(), 0, getScrollRange(), 0, 0, true); lastScrollDelta = 0; } int mTop = 10; public void scrollTo(View targetView) { int oldScrollY = getScrollY(); int top = targetView.getTop() - mTop; int delatY = top - oldScrollY; lastScrollDelta = delatY; overScrollBy(0, delatY, 0, getScrollY(), 0, getScrollRange(), 0, 0, true); } private int getScrollRange() { int scrollRange = 0; if (getChildCount() > 0) { View child = getChildAt(0); scrollRange = Math.max(0, child.getHeight() - (getHeight())); } return scrollRange; } int currentY; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (parentScrollView == null) { return super.onInterceptTouchEvent(ev); } else { View parentchild = parentScrollView.getChildAt(0); int height2 = parentchild.getMeasuredHeight(); height2 = height2 - parentScrollView.getMeasuredHeight(); int scrollY2 = parentScrollView.getScrollY(); if (ev.getAction() == MotionEvent.ACTION_DOWN) { if (scrollY2 >= height2){ // 将父scrollview的滚动事件拦截 currentY = (int) ev.getY(); setParentScrollAble(false); } } else if (ev.getAction() == MotionEvent.ACTION_UP) { // 把滚动事件恢复给父Scrollview setParentScrollAble(true); } else if (ev.getAction() == MotionEvent.ACTION_MOVE) { } } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) {// View child = getChildAt(0); if (parentScrollView != null) { if (ev.getAction() == MotionEvent.ACTION_MOVE) {// int height = child.getMeasuredHeight();// height = height - getMeasuredHeight(); int scrollY = getScrollY(); int y = (int) ev.getY(); View parentchild = parentScrollView.getChildAt(0); int height2 = parentchild.getMeasuredHeight(); height2 = height2 - parentScrollView.getMeasuredHeight(); int scrollY2 = parentScrollView.getScrollY(); if (scrollY2 >= height2) { // 手指向下滑动 if (currentY < y) { if (scrollY <= 0) { // 如果向下滑动到头,就把滚动交给父Scrollview setParentScrollAble(true); return false; } else { setParentScrollAble(false); } } /*else if (currentY > y) { if (scrollY >= height) { // 如果向上滑动到头,就把滚动交给父Scrollview setParentScrollAble(true); return false; } else { setParentScrollAble(false); } }*/ currentY = y; }/*else{ setParentScrollAble(true); }*/ } } return super.onTouchEvent(ev); } private void setParentScrollAble(boolean flag) { parentScrollView.requestDisallowInterceptTouchEvent(!flag); }}scrollview的代码:
public class NFScrollView extends ScrollView { public ScrollView parentScrollView; public int HeaderId; public int ContentContainerId; private int lastScrollDelta = 0; public NFScrollView(Context context) { super(context); setFocusable(false); } public NFScrollView(Context context, AttributeSet attrs) { super(context, attrs); setFocusable(false); } public NFScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setFocusable(false); } public void resume() { overScrollBy(0, -lastScrollDelta, 0, getScrollY(), 0, getScrollRange(), 0, 0, true); lastScrollDelta = 0; } int mTop = 10; public void scrollTo(View targetView) { int oldScrollY = getScrollY(); int top = targetView.getTop() - mTop; int delatY = top - oldScrollY; lastScrollDelta = delatY; overScrollBy(0, delatY, 0, getScrollY(), 0, getScrollRange(), 0, 0, true); } private int getScrollRange() { int scrollRange = 0; if (getChildCount() > 0) { View child = getChildAt(0); scrollRange = Math.max(0, child.getHeight() - (getHeight())); } return scrollRange; } int currentY; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (parentScrollView == null) { return super.onInterceptTouchEvent(ev); } else { View parentchild = parentScrollView.getChildAt(0); int height2 = parentchild.getMeasuredHeight(); height2 = height2 - parentScrollView.getMeasuredHeight(); int scrollY2 = parentScrollView.getScrollY(); if (ev.getAction() == MotionEvent.ACTION_DOWN) { if (scrollY2 >= height2) { // 将父scrollview的滚动事件拦截 currentY = (int) ev.getY(); setParentScrollAble(false); } } else if (ev.getAction() == MotionEvent.ACTION_UP) { // 把滚动事件恢复给父Scrollview setParentScrollAble(true); } else if (ev.getAction() == MotionEvent.ACTION_MOVE) { } } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { View child = getChildAt(0); if (parentScrollView != null) { if (ev.getAction() == MotionEvent.ACTION_MOVE) { int height = child.getMeasuredHeight(); height = height - getMeasuredHeight(); int scrollY = getScrollY(); int y = (int) ev.getY(); View parentchild = parentScrollView.getChildAt(0); int height2 = parentchild.getMeasuredHeight(); height2 = height2 - parentScrollView.getMeasuredHeight(); int scrollY2 = parentScrollView.getScrollY(); if (scrollY2 >= height2) { // 手指向下滑动 if (currentY < y) { if (scrollY <= 0) { // 如果向下滑动到头,就把滚动交给父Scrollview setParentScrollAble(true); return false; } else { setParentScrollAble(false); } } /*else if (currentY > y) { if (scrollY >= height) { // 如果向上滑动到头,就把滚动交给父Scrollview setParentScrollAble(true); return false; } else { setParentScrollAble(false); } }*/ currentY = y; } } /*else { setParentScrollAble(true); }*/ } return super.onTouchEvent(ev); } private void setParentScrollAble(boolean flag) { parentScrollView.requestDisallowInterceptTouchEvent(!flag); }}
效果图中的tab1、tab2、tab3分别对应的是recyclerview、webview、scrollview。这个就是自定义的三个控件的实现,主要是多了一些事件传递过程中的处理代码。布局中的示例图如下:
由此可见只是使用了自定义的三个组件,其他的组件不用做处理用Android原生的就行了,只是把tab1、2、3、4的高度加上viewpager的高度等于最外层scrollview的高度就行了。我的实现也就是在MainActivity中的实现如此:
public class MainActivity extends AppCompatActivity { private RadioButton item1; private RadioButton item2; private RadioButton item3; private RadioButton item4; private ScrollView outer; private int ids[] = {R.id.item1, R.id.item2, R.id.item3, R.id.item4}; private RadioGroup header; private ViewPager viewPager; private List<Fragment> frgs = new ArrayList<Fragment>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); outer=(ScrollView)super.findViewById(R.id.outer); header=(RadioGroup)super.findViewById(R.id.header); viewPager=(ViewPager)super.findViewById(R.id.view_pager); final View view = outer; view.post(new Runnable() { @Override public void run() { ViewGroup.LayoutParams containerparams = viewPager.getLayoutParams(); containerparams.height = outer.getHeight() - header.getHeight(); viewPager.setLayoutParams(containerparams); } }); TabOneFrg tab1 = new TabOneFrg(); tab1.outer = this.outer; frgs.add(tab1); TabTwoFrg tab2 = new TabTwoFrg(); tab2.outer = this.outer; frgs.add(tab2); TabThreeFrg tab3 = new TabThreeFrg(); tab3.outer = this.outer; frgs.add(tab3); TabFourFrg tab4 = new TabFourFrg(); tab4.outer = this.outer; frgs.add(tab4); viewPager.setAdapter(new TestViewPagerAdapter(getSupportFragmentManager(), frgs)); viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { header.check(ids[position]); } @Override public void onPageScrollStateChanged(int state) { } }); }}
final View view = outer; view.post(new Runnable() { @Override public void run() { ViewGroup.LayoutParams containerparams = viewPager.getLayoutParams(); containerparams.height = outer.getHeight() - header.getHeight(); viewPager.setLayoutParams(containerparams); } });这几句就是设置tab的高度加上viewpager的高度正好等于最外层scrollview的高度。
TabOneFrg tab1 = new TabOneFrg(); tab1.outer = this.outer; frgs.add(tab1); TabTwoFrg tab2 = new TabTwoFrg(); tab2.outer = this.outer; frgs.add(tab2); TabThreeFrg tab3 = new TabThreeFrg(); tab3.outer = this.outer; frgs.add(tab3); TabFourFrg tab4 = new TabFourFrg(); tab4.outer = this.outer;这几句中的
tab1.outer = this.outer;是把外层的scrollview传入fragment进而传到自定义的组件中。三个自定义组件中都有
public ScrollView parentScrollView;这个变量,最终fragment会把最外层的scrollview传入到此变量中。以此来监听最外层scrollview的滑动状态。
再把mainactivity的xml布局文件贴一下:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ScrollView android:id="@+id/outer" android:descendantFocusability="beforeDescendants" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <Button android:layout_width="match_parent" android:layout_height="300dp" android:gravity="center" android:textColor="#fff" android:text="header" android:background="#f00" /> <RadioGroup android:id="@+id/header" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <RadioButton android:id="@+id/item1" android:layout_width="0dp" android:layout_height="50dp" android:layout_weight="200" android:button="@null" android:checked="true" android:gravity="center" android:text="tab1" android:textColor="@drawable/tabcolor" /> <RadioButton android:id="@+id/item2" android:layout_width="0dp" android:layout_height="50dp" android:layout_weight="200" android:button="@null" android:gravity="center" android:text="tab2" android:textColor="@drawable/tabcolor" /> <RadioButton android:id="@+id/item3" android:layout_width="0dp" android:layout_height="50dp" android:layout_weight="200" android:button="@null" android:gravity="center" android:text="tab3" android:textColor="@drawable/tabcolor" /> <RadioButton android:id="@+id/item4" android:layout_width="0dp" android:layout_height="50dp" android:layout_weight="200" android:button="@null" android:gravity="center" android:text="tab4" android:textColor="@drawable/tabcolor" /> </RadioGroup> <View android:layout_width="match_parent" android:layout_height="1px" android:background="#ccc" /> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent"></android.support.v4.view.ViewPager> </LinearLayout> </ScrollView></RelativeLayout>
最后再把tabfragment贴出来:
TabOneFrg:
public class TabOneFrg extends Fragment { NFRecyclerView rvList; public ScrollView outer; public int header; public int content; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.frg_first, null); rvList=(NFRecyclerView)view.findViewById(R.id.rv_list); rvList.parentScrollView=outer; rvList.HeaderId=header; rvList.ContentContainerId=content; rvList.setLayoutManager(new LinearLayoutManager(getActivity())); rvList.setAdapter(new TestAdapter()); return view; } @Override public void onDestroyView() { super.onDestroyView(); }}
frg_first:
<?xml version="1.0" encoding="utf-8"?><com.ningfengview.NFRecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rv_list" android:layout_width="match_parent" android:layout_height="match_parent"></com.ningfengview.NFRecyclerView>
TabTwoFrg:
package com.example.akazam.scrolltest;import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.webkit.WebView;import android.webkit.WebViewClient;import android.widget.ScrollView;import com.example.akazam.scrolltest.ningfengview.NFWebView;public class TabTwoFrg extends Fragment { NFWebView rvList; public ScrollView outer; public int header; public int content; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.frg_two, null); rvList=(NFWebView)view.findViewById(R.id.rv_list); rvList.setVerticalScrollBarEnabled(false); rvList.setVerticalScrollbarOverlay(false); rvList.setHorizontalScrollBarEnabled(false); rvList.setHorizontalScrollbarOverlay(false); rvList.getSettings().setJavaScriptEnabled(true); rvList.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return super.shouldOverrideUrlLoading(view, url); } }); rvList.parentScrollView=outer; rvList.HeaderId=header; rvList.ContentContainerId=content; rvList.loadUrl("http://www.baidu.com"); return view; } @Override public void onDestroyView() { super.onDestroyView(); }}
frg_two:
<?xml version="1.0" encoding="utf-8"?><com.ningfengview.NFWebView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rv_list" android:layout_width="match_parent" android:layout_height="match_parent"></com.ningfengview.NFWebView>
TabThreeFrg:
public class TabThreeFrg extends Fragment { NFScrollView rvList; public ScrollView outer; public int header; public int content; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.frg_three, null); rvList=(NFScrollView)view.findViewById(R.id.rv_list); rvList.parentScrollView=outer; rvList.HeaderId=header; rvList.ContentContainerId=content; return view; } @Override public void onDestroyView() { super.onDestroyView(); }}
frg_three:
<?xml version="1.0" encoding="utf-8"?><com.ningfengview.NFScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rv_list" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:orientation="vertical" android:layout_height="wrap_content"> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> <EditText android:layout_width="match_parent" android:gravity="center" android:text="测试测试" android:layout_height="wrap_content" /> </LinearLayout></com.ningfengview.NFScrollView>
以上就是主要的代码。最后把adapter的代码也粘贴一下:
TestViewPagerAdapter:
public class TestViewPagerAdapter extends FragmentStatePagerAdapter { private List<Fragment> mData; public TestViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) { super(fm); this.mData=fragments; } @Override public Fragment getItem(int position) { return mData.get(position); } @Override public int getCount() { return mData.size(); } @Override public void destroyItem(ViewGroup container, int position, Object object) {// super.destroyItem(container, position, object); }}
TestAdapter:
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyViewHolder> { @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_test, null); MyViewHolder viewHolder = new MyViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.title.setText("" + position); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(),"item click",Toast.LENGTH_SHORT).show(); } }); } @Override public int getItemCount() { return 500; } static class MyViewHolder extends RecyclerView.ViewHolder { EditText title; MyViewHolder(View view) { super(view); this.title=(EditText)view.findViewById(R.id.title); } }}item_test:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"><EditText android:id="@+id/title" android:layout_width="match_parent" android:text="afsfdafdjalsdfj" android:layout_height="wrap_content" /></RelativeLayout>
以上就是实现该效果的所有代码。
其核心就是三个可滑动的自定义组件,并且把自定义组件和tab的高度之和设置成最外层的scrollview的高度并把最外层的scrollview传入到自定义控件中的parentScrollView
即可以。有问题可以给我留言。
- 高仿360手机助手应用详情页和贝贝商品详情页的实现
- android悬浮控件-仿360手机助手应用详情页
- 修改android-自定义控件-悬浮控件-仿360手机助手应用详情页
- 自定义ViewGroup实现仿淘宝的商品详情页
- android 自定义ViewGroup实现仿淘宝的商品详情页
- android 自定义ViewGroup实现仿淘宝的商品详情页
- android 自定义ViewGroup实现仿淘宝的商品详情页
- 仿淘宝商品详情页,上拉查看更多详情demo(Activity和Fragment)。2种应用场景
- Android 自定义Viewgroup之仿360手机助手详情页图片滑动
- 仿淘宝商品详情页TabLayout+ListView
- 高仿淘宝商品详情标题栏渐变
- 商品详情页显示商品的详细信息
- Android 商品详情页
- 商品详情页+tablayout
- 京东商品详情页技术实现
- Android_实现商品详情的展示页及布局
- Android 仿淘宝商品详情页下拉足迹Demo
- 【项目实战】---商品详情页的制作
- Android Fragment中onActivityResult()方法获取不到返回数据或者无响应的解决办法
- AppStore申请加急审核
- ScrollView和ListView滚动手势冲突解决方法
- 趣学Python-教孩子学编程--第九章
- bitmap将头像转换为圆形头像
- 高仿360手机助手应用详情页和贝贝商品详情页的实现
- 发起中文邮件项目,寻志愿者
- set echo on/off,set term on/off,set feedback off,set heading off命令
- js调用手机摄像头
- android 异常处理----发送邮件
- Git的三级缓存
- LeetCode 129 Sum Root to Leaf Numbers
- android中onActivityResult方法无法获取返回的resultCode和data问题
- COM组件