Android CollapsingToolbarLayout सूची श्रोता


106

मैं के CollapsingToolBarLayoutसाथ AppBarLayoutऔर उपयोग कर रहा हूँ CoordinatorLayout, और वे पूरी तरह से ठीक काम कर रहे हैं। Toolbarजब मैंने स्क्रॉल किया तो मैंने इसे ठीक करने के लिए सेट किया, मैं जानना चाहता हूं कि क्या टूलबार के शीर्षक पाठ को बदलने का कोई तरीका है, जब CollapsingToolBarLayoutयह ढह जाता है।

लपेटकर, मैं दो अलग-अलग शीर्षक चाहता हूं जब स्क्रॉल किया जाता है और जब विस्तारित होता है

एडवांस में आप सभी को धन्यवाद

जवाबों:


150

मैं @Frodio Beggins और @ निफ़ेल कोड के आधार पर पूर्ण कार्यान्वयन साझा करता हूं:

public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {

    public enum State {
        EXPANDED,
        COLLAPSED,
        IDLE
    }

    private State mCurrentState = State.IDLE;

    @Override
    public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
        if (i == 0) {
            if (mCurrentState != State.EXPANDED) {
                onStateChanged(appBarLayout, State.EXPANDED);
            }
            mCurrentState = State.EXPANDED;
        } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
            if (mCurrentState != State.COLLAPSED) {
                onStateChanged(appBarLayout, State.COLLAPSED);
            }
            mCurrentState = State.COLLAPSED;
        } else {
            if (mCurrentState != State.IDLE) {
                onStateChanged(appBarLayout, State.IDLE);
            }
            mCurrentState = State.IDLE;
        }
    }

    public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
}

और फिर आप इसका उपयोग कर सकते हैं:

appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
    @Override
    public void onStateChanged(AppBarLayout appBarLayout, State state) {
        Log.d("STATE", state.name());
    }
});

21
यह सही है। लेकिन कृपया यह नहीं कि प्रोगार्ड का उपयोग करते हुए कि एनम एक पूर्णांक मान में अनुवादित होने जा रहा है।
rciovati

1
मुझे नहीं पता था। एक दम बढ़िया!
टिम ६।

2
इसके अलावा enums प्रकार सुरक्षा सुनिश्चित करने का एक बहुत अच्छा तरीका है। आपके पास State.IMPLODED नहीं हो सकता क्योंकि यह मौजूद नहीं है (कंपाइलर शिकायत करेगा) लेकिन Integer constants के साथ आप ऐसा मान इस्तेमाल कर सकते हैं कि कंपाइलर को पता न चले कि यह गलत है। वे एकल के रूप में भी अच्छे हैं, लेकिन एक और कहानी है।
droppin_science

एंड्रॉयड enums के लिए @droppin_science की जाँच IntDef
डेविड Darias

1
@ दाविदियारस व्यक्तिगत रूप से मैं अपने ओवरहेड के साथ भी एक बहुत क्लीनर दृष्टिकोण enums पाते हैं (यहाँ तर्क शुरू ... :-)
droppin_science

95

यह समाधान मेरे लिए पूरी तरह से AppBarLayoutढह गया या विस्तारित का पता लगाने के लिए काम करता है ।

appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

            if (Math.abs(verticalOffset)-appBarLayout.getTotalScrollRange() == 0)
            {
                //  Collapsed


            }
            else
            {
                //Expanded


            }
        }
    });

पर इस्तेमाल addOnOffsetChangedListenerकिया गया AppBarLayout


36

OnOffsetChangedListenerअपने को हुक AppBarLayout। जब ऊंचाई verticalOffsetतक 0 या उससे कम पहुंचता है Toolbar, तो इसका मतलब है कि CollapsingToolbarLayout ध्वस्त हो गया है, अन्यथा यह विस्तार या विस्तार कर रहा है।

mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if(verticalOffset == 0 || verticalOffset <= mToolbar.getHeight() && !mToolbar.getTitle().equals(mCollapsedTitle)){
                    mCollapsingToolbar.setTitle(mCollapsedTitle);
                }else if(!mToolbar.getTitle().equals(mExpandedTitle)){
                    mCollapsingToolbar.setTitle(mExpandedTitle);
                }

            }
        });

1
यह मेरे लिए काम नहीं कर रहा है। OnCollapse मैं होम बटन को सक्षम करना चाहता हूं और होम बटन को विस्तृत करें
महेश्वर Ligade

9
जब टूलबार पूरी तरह से विस्तारित हो जाता है, और फिर ढहते समय नकारात्मक हो जाता है, तो वर्टिकल ऑफ़सेट मान शून्य हो जाता है। जब टूलबार ढह जाता है, तो वर्टिकलऑफसेट, टूलबार की ऊंचाई (-mToolbar.getHeight ()) के बराबर होता है। तो ... टूलबार को आंशिक रूप से विस्तारित किया जाता है "यदि (वर्टिकलऑफ़सेट> -mToolbar.getHeight ())"
माइक

यदि कोई यह सोच रहा है कि appBarLayout.getVerticalOffset()विधि कहाँ है, तो आप appBarLayout.getY()कॉलबैक में उपयोग किए जाने वाले मान को पुनः प्राप्त करने के लिए कॉल कर सकते हैं ।
जरीट मिलार्ड

दुर्भाग्य से जरीट मिलार्ड सही नहीं है। आपके फिट बैठता है सिस्टमविंडो कॉन्फ़िगरेशन और स्टेटसबार कॉन्फ़िगरेशन (पारदर्शी) के आधार पर appBarLayout.getY()यह हो सकता है किverticalOffset = appBarLayout.getY() + statusBarHeight
मकर

1
क्या किसी ने देखा है कि अगर mAppBarLayout.addOnOffsetChangedListener (श्रोता) को बार-बार बुलाया जाता है, भले ही हम वास्तव में ऐपबार के साथ बातचीत न कर रहे हों? या यह मेरे लेआउट / ऐप में एक बग है जहां मैं इस व्यवहार को देख रहा हूं। Plz की मदद!
राहुल शुक्ला

16

इस कोड ने मेरे लिए काम किया

mAppBarLayout.addOnOffsetChangedListener(new   AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            if (verticalOffset == -mCollapsingToolbarLayout.getHeight() + mToolbar.getHeight()) {
                //toolbar is collapsed here
                //write your code here
            }
        }
    });

निकोला देसपोत्सोकी से बेहतर जवाब
विग्नेश बाला

एक विश्वसनीय समाधान नहीं लगता है। लेकिन यह -693 के बराबर है mCollapsingToolbarLayout.getHeight () = 1013, mToolbar.getHeight () 224 = तो संक्षिप्त रूप में अपने समाधान verticalOffset के अनुसार -789 होना चाहिए,: मैं इसे और अपने डिवाइस पर मूल्यों का अनुसरण कर रहे परीक्षण किया
सिंह डायरकोडर

16
private enum State {
    EXPANDED,
    COLLAPSED,
    IDLE
}

private void initViews() {
    final String TAG = "AppBarTest";
    final AppBarLayout mAppBarLayout = findViewById(R.id.appbar);
    mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        private State state;

        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            if (verticalOffset == 0) {
                if (state != State.EXPANDED) {
                    Log.d(TAG,"Expanded");
                }
                state = State.EXPANDED;
            } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {
                if (state != State.COLLAPSED) {
                    Log.d(TAG,"Collapsed");
                }
                state = State.COLLAPSED;
            } else {
                if (state != State.IDLE) {
                    Log.d(TAG,"Idle");
                }
                state = State.IDLE;
            }
        }
    });
}

10

आप नीचे का उपयोग करके collapsingToolBar अल्फा प्रतिशत प्राप्त कर सकते हैं:

appbarLayout.addOnOffsetChangedListener( new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            float percentage = ((float)Math.abs(verticalOffset)/appBarLayout.getTotalScrollRange());
            fadedView.setAlpha(percentage);
    });

संदर्भ के लिए: लिंक


2
यह एक महान जवाब है क्योंकि यह एक सामान्यीकृत ऑफसेट देता है। मेरी राय में, एपीआई को verticalOffsetपिक्सेल दूरी के बजाय सीधे यह प्रदान करना चाहिए था ।
dbm

5

यहाँ एक कोटलिन समाधान है। एक जोड़े OnOffsetChangedListenerके लिए AppBarLayout

विधि A:

AppBarStateChangeListener.ktअपने प्रोजेक्ट में जोड़ें :

import com.google.android.material.appbar.AppBarLayout
import kotlin.math.abs

abstract class AppBarStateChangeListener : AppBarLayout.OnOffsetChangedListener {

    enum class State {
        EXPANDED, COLLAPSED, IDLE
    }

    private var mCurrentState = State.IDLE

    override fun onOffsetChanged(appBarLayout: AppBarLayout, i: Int) {
        if (i == 0 && mCurrentState != State.EXPANDED) {
            onStateChanged(appBarLayout, State.EXPANDED)
            mCurrentState = State.EXPANDED
        }
        else if (abs(i) >= appBarLayout.totalScrollRange && mCurrentState != State.COLLAPSED) {
            onStateChanged(appBarLayout, State.COLLAPSED)
            mCurrentState = State.COLLAPSED
        }
        else if (mCurrentState != State.IDLE) {
            onStateChanged(appBarLayout, State.IDLE)
            mCurrentState = State.IDLE
        }
    }

    abstract fun onStateChanged(
        appBarLayout: AppBarLayout?,
        state: State?
    )

}

श्रोता को इसमें जोड़ें appBarLayout:

appBarLayout.addOnOffsetChangedListener(object: AppBarStateChangeListener() {
        override fun onStateChanged(appBarLayout: AppBarLayout?, state: State?) {
            Log.d("State", state.name)
            when(state) {
                State.COLLAPSED -> { /* Do something */ }
                State.EXPANDED -> { /* Do something */ }
                State.IDLE -> { /* Do something */ }
            }
        }
    }
)

विधि B:

appBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
        if (abs(verticalOffset) - appBarLayout.totalScrollRange == 0) { 
            // Collapsed
        } else if (verticalOffset == 0) {
            // Expanded
        } else {
            // Idle
        }
    }
)

3

यह समाधान मेरे लिए काम कर रहा है:

@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
  if (i == 0) {
    if (onStateChangeListener != null && state != State.EXPANDED) {
      onStateChangeListener.onStateChange(State.EXPANDED);
    }
    state = State.EXPANDED;
  } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
    if (onStateChangeListener != null && state != State.COLLAPSED) {
      onStateChangeListener.onStateChange(State.COLLAPSED);
    }
    state = State.COLLAPSED;
  } else {
    if (onStateChangeListener != null && state != State.IDLE) {
      onStateChangeListener.onStateChange(State.IDLE);
    }
    state = State.IDLE;
  }
}

AppBarLayout पर addOnOffsetChangedListener का उपयोग करें।


क्या आप अपना पूरा कोड साझा कर सकते हैं? State.EXPANDED आदि क्या है?
चेतना

1

यदि आप CollapsingToolBarLayout का उपयोग कर रहे हैं तो आप इसे लगा सकते हैं

collapsingToolbar.setExpandedTitleColor(ContextCompat.getColor(activity, android.R.color.transparent));
collapsingToolbar.setTitle(title);

1

यह कोड मेरे लिए एकदम सही काम कर रहा है। आप प्रतिशत पैमाने का उपयोग कैसे कर सकते हैं

@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
    double percentage = (double) Math.abs(verticalOffset) / collapsingToolbar.getHeight();
    if (percentage > 0.8) {
        collapsingToolbar.setTitle("Collapsed");
    } else {
        collapsingToolbar.setTitle("Expanded");
    }
}

0

मेरे टूलबार ऑफ़सेट का मान -582 हो जाता है जब पतन होता है, तो विस्तार = 0 पर इसलिए मैं टोस्ट में ऑफसेट सेट करके और तदनुसार कोड परिवर्तित करके मान प्राप्त करता हूं।

 mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            if(verticalOffset == -582) {
            Toast.makeText(MainActivity.this, "collaped" + verticalOffset, Toast.LENGTH_SHORT).show();
            mCollapsingToolbarLayout.setTitle("Collapsed");
            }else if(verticalOffset == 0){
                Toast.makeText(MainActivity.this, "expanded" + verticalOffset, Toast.LENGTH_SHORT).show();
            mCollapsingToolbarLayout.setTitle("expanded");
            }
        }
    });
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.