Solution to Android sliding conflicts (2)

Source: Internet
Author: User
Tags gety

Solution to Android sliding conflicts (2)

The previous study notes mainly focused on how to understand the conflicts caused by sliding in different directions in Android. These conflicts are easy to understand and can be easily solved. Today, let's take a look at the conflict caused by sliding in the same direction. Here we take the sliding conflict in the vertical direction as the background, which is also the most common situation in daily development.

Let's take a look at it first.

Due to the limited size of GIF images, the effect is not very good.

It is commonly used in shopping software to pull up and view graphic details. There are many ways to achieve the overall effect of the animation effect. There are many related examples on the Internet, however, the processing of some details is not very clear. For example, if the part displayed after the drop-down (such as the image details at the bottom) is a ScrollView-like control (such as WebView, new problems may occur. Here we will show the text details as the background for the analysis of sliding conflicts in the same direction.

Overall Thinking

See here

First, make some settings for this figure:

The black box indicates the mobile phone screen. A green box represents an outer ScrollView. Two red boxes represent two classes of ScrollView Control 1 nested in it. Here we are short for SUp and SDown.

Now, let's analyze the process of implementing the entire process.

It must be clarified that, at any time, the visible parts of SUp and SDown are always the height of the mobile phone screen. To learn this, follow these steps:

First, we ensure that the external ScrollView does not intercept the sliding event, so that SUp will inevitably obtain the event, and then according to its Action_Move event, when it isSlide downAndSliding distance + screen height = heightYou can think that the SUp slides to the bottom. In this case, the external ScrollView can intercept the sliding event to ensure that the sliding event can continue to slide down. At this time, the bottom SDown is displayed.

Similarly, in this case, the external ScrollView does not allow the external ScrollView to intercept the sliding event, which is handled by SDown. Based on the Action_move event, when it is a sliding upward event and its sliding distance is 0, it means that the SDown has slipped to the top, and the external ScrollView can get the right to intercept the sliding event, so as to ensure that the entire view can continue to slide up, SUp is displayed again, A new round of loop interception has been started.

In this way, the overall process can achieve the animation effect. Now, let's talk about the principle and check the code.

Code Implementation SUp implementation
Public class UpScrollView extends ScrollView {/*** screen height */private int mScreenHeight;/*** last coordinate */private float mLastY; /*** sliding distance of the current View */private int mScrollY;/***** height of the Child control in the current View */private int mChildH; public UpScrollView (Context context) {super (context); init (context);} public UpScrollView (Context context, AttributeSet attrs) {super (context, attrs); init (context );} public UpScrollView (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); init (context);} private void init (Context context) {WindowManager wm = (WindowManager) context. getSystemService (Context. WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics (); wm. getdefadisplay display (). getMetrics (dm); mScreenHeight = dm. heightPixels ;}@ Override public boolean onTouchEvent (MotionEvent ev) {// by default, the top-level View does not intercept getParent (). getParent (). requestDisallowInterceptTouchEvent (true); switch (ev. getAction () {case MotionEvent. ACTION_DOWN: mLastY = (int) ev. getY (); break; case MotionEvent. ACTION_MOVE: float y = ev. getY (); float deltaY = y-mLastY; mChildH = this. getChildAt (0 ). getMeasuredHeight (); int translateY = mChildH-mScrollY; // when sliding up, if the translateY is equal to the screen height, it indicates sliding to the bottom, you can control the sliding if (deltaY <0 & translateY = mScreenHeight) {getParent () on the top View (). getParent (). requestDisallowInterceptTouchEvent (false);} break; default: break;} return super. onTouchEvent (ev) ;}@ Override protected void onScrollChanged (int l, int t, int oldl, int oldt) {super. onScrollChanged (l, t, oldl, oldt); mScrollY = t ;}}

Here, the subtraction is done in ACTION_MOVE. The truth is the same.

OnScrollChanged is implemented in the View class. View its API and you can see its second parameter t explanation.

@ Param t Current vertical scroll origin.

That is, the sliding distance of the current View.

SDown implementation
public class MyWebView extends WebView {    public float oldY;    private int t;    public MyWebView(Context context) {        super(context);        init();    }    public MyWebView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    private void init() {        WebSettings settings = getSettings();        settings.setJavaScriptEnabled(true);        setWebViewClient(new WebViewClient() {            @Override            public boolean shouldOverrideUrlLoading(WebView view, String url) {                view.loadUrl(url);                return true;            }        });    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        getParent().getParent().requestDisallowInterceptTouchEvent(true);        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                oldY = ev.getY();                break;            case MotionEvent.ACTION_MOVE:                float Y = ev.getY();                float Ys = Y - oldY;                if (Ys > 0 && t == 0) {                    getParent().getParent().requestDisallowInterceptTouchEvent(false);                }                break;        }        return super.onTouchEvent(ev);    }    @Override    protected void onScrollChanged(int l, int t, int oldl, int oldt) {        this.t = t;        super.onScrollChanged(l, t, oldl, oldt);    }}

As you can see, the View at the bottom of this page does not inherit ScrollView, but instead inherits WebView. It is only for convenience. Of course, it is no problem to inherit ScrollView. Here, we only need to consider the actual situation, because the content of the image details at the bottom is a WebView loading data.

The implementation of this class should be well understood according to the principles mentioned earlier.

External ScrollView
Public class CustomerScrollViews extends ScrollView {/*** screen height */private int mScreenHeight; private UpScrollView upScrollView; private MyWebView myWebView; private boolean init = false; private float fator = 0.2f; private int factorHeight; private boolean upShow = true; public CustomerScrollViews (Context context) {super (context); init (context);} public CustomerScrollViews (Context context, Attr IbuteSet attrs) {super (context, attrs); init (context);} public CustomerScrollViews (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr ); init (context);} private void init (Context context) {WindowManager wm = (WindowManager) context. getSystemService (Context. WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics (); wm. getdefadisplay display (). getMetrics (dm); m ScreenHeight = dm. heightPixels; factorHeight = (int) (mScreenHeight * fator);} @ Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {if (! Init) {LinearLayout parentView = (LinearLayout) getChildAt (0); // obtain two internal child views upScrollView = (UpScrollView) parentView. getChildAt (0); myWebView = (MyWebView) parentView. getChildAt (2); // set its height to the screen height upScrollView. getLayoutParams (). height = mScreenHeight; myWebView. getLayoutParams (). height = mScreenHeight; init = true;} super. onMeasure (widthMeasureSpec, heightMeasureSpec);} @ Override protected void onLayout (boolean changed, int l, int t, int r, int B) {super. onLayout (changed, l, t, r, B); if (changed) {scrollTo (0, 0) ;}@ Override public boolean onTouchEvent (MotionEvent ev) {switch (ev. getAction () {case MotionEvent. ACTION_UP: int scrollY = getScrollY (); if (upShow) {if (scrollY <= factorHeight) {smoothScrollTo (0, 0);} else {smoothScrollTo (0, mScreenHeight ); upShow = false ;}} else {int scrollpadding = mScreenHeight-scrollY; if (scrollpadding> = factorHeight) {this. smoothScrollTo (0, 0); upShow = true;} else {this. smoothScrollTo (0, mScreenHeight) ;}} return true;} return super. onTouchEvent (ev );}}

The implementation of this class is flexible. After the internal View is initialized in the onMeasure method, different logic implementations can be completed in the OnTouch method according to actual needs, here, we just want to change the displacement of the entire view by using the ScrollView's smoothScrollTo method, which is quite simple.

Here we will focus on the following:

upScrollView = (UpScrollView) parentView.getChildAt(0);myWebView = (MyWebView) parentView.getChildAt(2);

You may wonder where the child (1) goes in the middle? Here we will start with the layout file of MainActivity.

Dual_scrollview_activity_layout1.xml


  
      
           
                
                     
       
        
         
          
         
        
       
                  
                 
                 
       
      
     
        
   
  

The layout file shows that two custom scrollviews are placed in the Custom ScrollView of the outermost layer of mermerscrollviews (as shown in the schematic diagram ), however, in the middle of the two ScrollView controls, a LinearLayout is placed through layout, and the content in the LinearLayout contains qq, baidu is used to switch a View of the WebView content. No code is posted here.

In this way, you can understand why the previous child (1) was skipped.

Use
public class DualScrollViewActivity1 extends Activity implements View.OnClickListener {    private MyWebView webView;    private TextView sinaTv, qqTv, baiduTv;    private View line1, line2, line3;    private final String BAIDU = "http://www.baidu.com";    private final String QQ = "http://www.qq.com";    private final String SINA = "http://sina.cn";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        InitView();        sinaTv.performClick();    }    private void InitView() {        setContentView(R.layout.dual_scrollview_activity_layout1);        webView = V.f(this, R.id.web);        sinaTv = V.f(this, R.id.one);        sinaTv.setOnClickListener(this);        qqTv = V.f(this, R.id.two);        qqTv.setOnClickListener(this);        baiduTv = V.f(this, R.id.three);        baiduTv.setOnClickListener(this);        line1 = V.f(this, R.id.line1);        line2 = V.f(this, R.id.line2);        line3 = V.f(this, R.id.line3);    }    @Override    public void onClick(View v) {        reset();        String url = "";        switch (v.getId()) {            case R.id.one:                line1.setVisibility(View.VISIBLE);                url = SINA;                break;            case R.id.two:                line2.setVisibility(View.VISIBLE);                url = QQ;                break;            case R.id.three:                line3.setVisibility(View.VISIBLE);                url = BAIDU;                break;            default:                break;        }        webView.loadUrl(url);    }    private void reset(){        line1.setVisibility(View.GONE);        line2.setVisibility(View.GONE);        line3.setVisibility(View.GONE);    }}

Here, we will update the content of the View at the bottom. WebView achieves different View effects by loading different URLs, just as a Demo test.

Here, the solution to the sliding conflict is expanded from the inside out. By default, the top View is out of interception, And the sliding distance from the bottom View is, different logic judgments are made to control the interception at the top layer. This is also easy to understand and implement. Of course, there are many different ideas about this kind of sliding conflict.

In actual development and developmentControls with the same direction of slidingDuring nesting, the problem is not just a sliding conflict, but sometimes the content is not displayed completely or not.

The most common example is ScrollView nested ListView. In this case, you only need to customize the ListView so that its height is calculated as a large value, which in a sense makes it lose the slide feature, however, this also makes the ListView seem to have lost the view recycling mechanism. In this case, if you load many, many, and many images, the effect will be unsatisfactory. In this case, adding headView and footView to ListView is also a solution, but the actual UI conditions must be allowed.

ScrollView nesting RecyclerView is a little tricky. You need to customize ScrollView and LinearLayoutManager.

It can be seen that there are still many problems after such controls with similar features are nested in Android. In this regard, Google has a thing called NestedScrolling. Next, we will study it to see its advantages in solving sliding conflicts.

  • ScrollView controls are similar to those with ScrollView features.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.