Theory
એક ફોન માટે ઝઘડતા ત્રણ પડદા
FestConnect Mobile પાસે હવે events ની યાદી, કાર્યક્રમનું સમયપત્રક અને વિદ્યાર્થીનો pass છે: content ના 3 આખા પડદા, અને એવી સમિતિ જેને એ ત્રણેય "એક જ tap દૂર, અને back button વગર" જોઈએ છે.
તમે રોજ વાપરો છો એ દરેક app એ આ સમસ્યા એક જ રીતે ઉકેલી છે: tab ની પટ્ટી: જેમ કે WhatsApp ના Chats, Status અને Calls, અને હવે તમારા Events, Schedule તથા My Pass.
Android આ કામ 2 widgets વચ્ચે વહેંચી નાખે છે: એક પટ્ટી દોરે છે અને સંભાળે છે, અને બીજું, જે SDK નું સૌથી નમ્ર પાત્ર છે, એ મંચ સાચવે છે જેને એ બધાં વહેંચે છે.
Theory
FrameLayout: પારદર્શક પડોનો થપ્પો
FrameLayout લગભગ કશું જ કરતું નથી, અને એ જ એની ખૂબી છે: એનાં children હરોળ કે થાંભલામાં ગોઠવાતાં નથી: એ એક જ frame માં એકની ઉપર એક ખડકાય છે, અને દરેક પોતાની પહેલાંના પર દોરાય છે, એટલે XML માં છેલ્લે આવતું child સૌથી ઉપર બેસે છે.
એમાંથી બે કામ આપોઆપ નીકળે છે:
- ઉપર ચડાવેલા પડ: poster વાળા child ઉપર દોરાયેલું "SOLD OUT" નું પટ્ટીવાળું child; frame ની અંદર children ને
layout_gravityવડે ગોઠવો - બદલી શકાય એવો મંચ: ત્રણેય વિભાગનાં views એક જ FrameLayout ની અંદર મૂકો અને એક સમયે એક જ બતાવો: tab વાળા ઢાંચાનું આ બીજું અડધિયું
Theory
TabLayout: નક્કી કરતી પટ્ટી
TabLayout (Material library માંથી) tab ની પટ્ટી અને એની નીચે સરકતી શાહીની લીટીનું animation દોરે છે. Tabs બેમાંથી કોઈ પણ રીતે બનાવો:
tabs.addTab(tabs.newTab().setText("Events"));
અથવા XML માં <TabItem> children તરીકે. પછી સાંભળો:
tabs.addOnTabSelectedListener(...), જેમાં 3 callbacks હોય છે: onTabSelected (નવું tab પસંદ થયું: અહીં કામ કરો, અને કયું એ tab.getPosition() કહી દે છે), onTabUnselected (જૂનું tab ધ્યાન ગુમાવે ત્યારે), અને onTabReselected (ચાલુ tab ને ફરી tap કરો ત્યારે: apps અહીં ઘણી વાર ઉપર સુધી scroll કરી દે છે).
પટ્ટી નક્કી કરે છે; બતાવવાનું કામ કોઈ બીજાએ કરવું પડે: અહીં FrameLayout પ્રવેશે છે.
Practical
Frame નું દેખાતું child બદલતાં tabs
public class MainActivity extends AppCompatActivity {
View eventsView, scheduleView, passView;
@Override
protected void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.activity_main); // FrameLayout ની ઉપર TabLayout
eventsView = findViewById(R.id.sectionEvents);
scheduleView = findViewById(R.id.sectionSchedule);
passView = findViewById(R.id.sectionPass);
TabLayout tabs = findViewById(R.id.tabs);
tabs.addTab(tabs.newTab().setText("Events"));
tabs.addTab(tabs.newTab().setText("Schedule"));
tabs.addTab(tabs.newTab().setText("My Pass"));
tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override public void onTabSelected(TabLayout.Tab tab) {
eventsView.setVisibility(tab.getPosition() == 0 ? View.VISIBLE : View.GONE);
scheduleView.setVisibility(tab.getPosition() == 1 ? View.VISIBLE : View.GONE);
passView.setVisibility(tab.getPosition() == 2 ? View.VISIBLE : View.GONE);
}
@Override public void onTabUnselected(TabLayout.Tab tab) { }
@Override public void onTabReselected(TabLayout.Tab tab) { }
});
}
}
Quiz
XML માં એક FrameLayout ની અંદર પહેલાં ImageView (poster) અને પછી TextView ("SOLD OUT") છે. વપરાશકારને શું દેખાશે?
- LinearLayout ની જેમ ઊભા ક્રમમાં, લખાણની ઉપર poster
- Poster ની ઉપર દોરાયેલું SOLD OUT નું લખાણ: FrameLayout children ને એકની ઉપર એક ખડકે છે, અને છેલ્લું child સૌથી ઉપર રહે છે
- ફક્ત poster: FrameLayout ફક્ત પોતાનું પહેલું child જ બતાવે છે
- Crash: ScrollView ની જેમ FrameLayout પણ ફક્ત એક જ child ને ચાલવા દે છે
Show the answer
Poster ની ઉપર દોરાયેલું SOLD OUT નું લખાણ: FrameLayout children ને એકની ઉપર એક ખડકે છે, અને છેલ્લું child સૌથી ઉપર રહે છે
FrameLayout એ પારદર્શક પડોનો થપ્પો છે: દરેક child એ જ frame રોકે છે અને XML ના ક્રમમાં રંગાય છે, એટલે પછી આવતું TextView poster ઉપર ચડી જાય છે: badges, પાણીછાપ અને sold-out ની પટ્ટીઓ બરાબર આ જ રીતે બને છે. વિકલ્પ A LinearLayout વાળી હરોળની ગોઠવણ અહીં ઘુસાડે છે, જ્યારે આ પાત્ર જાણી જોઈને ગોઠવણ કરતું નથી. વિકલ્પ C એને ViewSwitcher જેવા widget સાથે ગૂંચવે છે: અહીં તો બધાં children દોરાય છે, જો એમની visibility એ થવા દે તો. વિકલ્પ D ત્રણ પાઠ પહેલાંનો ScrollView વાળો એક જ child નો નિયમ ઉછીનો લે છે: FrameLayout અનેક children ને ખુશીથી સ્વીકારે છે: એકબીજા પર ચડી જવું એ એની ખૂબી છે, ખામી નહીં.
Think first
GONE શા માટે, અને reselect શા માટે?
ઉપરના listing ના બે design વાંચનો: (અ) સંતાડેલા વિભાગો View.INVISIBLE ને બદલે View.GONE વાપરે છે: બંને વચ્ચે શો ફરક છે અને અહીં GONE શા માટે બંધબેસે છે? (બ) તમે ખરેખર ક્યારે onTabReselected માં code લખશો? વિચારીને પછી tap કરો.
Show the answer
(અ) INVISIBLE view ને સંતાડે છે ખરું, પણ layout માં એની જગ્યા રોકાયેલી જ રહે છે; GONE એને layout માંથી સાવ કાઢી નાખે છે, જાણે એ હાજર જ ન હોય. એકની ઉપર એક ખડકાયેલા આખા પડદાના વિભાગોને GONE જ જોઈએ: કોઈએ ભૂતિયા જગ્યા રોકવી ન જોઈએ (FrameLayout ની અંદર તો બંને children એકબીજા પર ચડે જ છે, પણ GONE સંતાયેલા views ને સ્પર્શ ઝીલતાં અને માપ લેવાતાં પણ અટકાવે છે).
(બ) onTabReselected ત્યારે ચાલે છે જ્યારે ચાલુ tab ને ફરી tap કરવામાં આવે: ઓપવાળી apps ની રૂઢિ એ છે કે અહીં ઉપર સુધી scroll કરી દેવું કે યાદી તાજી કરવી: તમે WhatsApp ના Chats tab પર જ હો ત્યારે એને ફરી દબાવો છો એ યાદ કરો. ત્રણેય callbacks નાં કામ જાણવાં એ જ tabs ને ફક્ત જોડી જાણવા અને એમને સમજવા વચ્ચેનો ફરક છે.
Watch out
Tabs માં થતી ભૂલો
App ખૂલે ત્યારે કશું જ દેખાતું નથી: listener તો પસંદગી બદલાય ત્યારે જ ચાલે છે: એટલે શરૂઆતની visibility તમારે જાતે ગોઠવવી પડે (અથવા code થી tab 0 પસંદ કરી લેવું), નહીં તો frame ખાલી કે એકબીજા પર ચડેલા views સાથે શરૂ થાય છે.
ત્રણેય methods ફરજિયાત છે: OnTabSelectedListener એ interface છે: જે ન વાપરવાં હોય એમને ખાલી શરીર આપો, નહીં તો compile જ નહીં થાય (એ જ TextWatcher વાળો નિયમ).
ભારે views જીવતાં રહી જાય છે: આ ઢાંચામાં ત્રણેય વિભાગ memory માં હાજર જ રહે છે: 3 માટે વાંધો નહીં, પણ 10 માટે નકામો બોજ: એટલા માટે જ ખરી apps TabLayout ને ViewPager2 તથા fragments સાથે જોડે છે, જે અભ્યાસક્રમની બહારનો સુધારો છે અને પરીક્ષામાં પાદટીપ તરીકે લખવા જેવો છે.
Theory
Unit 1 પૂરું: Android વાળું અડધિયું પતી ગયું
FestConnect Mobile હવે scroll થાય છે, સમૃદ્ધ યાદીઓ બતાવે છે, તારીખ પસંદ કરાવે છે, શોધમાં સૂચનો આપે છે, posters સરકાવે છે અને પોતાને tabs માં ગોઠવે છે: એટલે કે ખરી app નો widget નો શબ્દભંડોળ, અને એ બધું Java તથા XML માં. આ ટોચ પર જરા શ્વાસ લો: હવે વિષય ભાષા જ બદલી નાખે છે. Unit 2 Dart નો પરિચય કરાવે છે, Unit 3 Flutter નો, અને Unit 5 સુધીમાં તમે આ જ પડદો ફરી બનાવશો: એ જ app, પણ નવું બ્રહ્માંડ: તમે ઢાંચા શીખ્યા કે ફક્ત syntax, એની આ સૌથી સારી કસોટી છે.
Summary
Key takeaways
- FrameLayout children ને એક જ frame માં ખડકે છે, XML ના ક્રમે નીચેથી ઉપર: ઉપર ચડાવેલા પડ અને બદલી શકાય એવો મંચ.
- layout_gravity child ને frame ની અંદર ગોઠવે છે; GONE એને layout માંથી કાઢી નાખે છે, જ્યારે INVISIBLE ફક્ત સંતાડે છે.
- TabLayout પટ્ટી દોરે છે: addTab(newTab().setText(...)), અને addOnTabSelectedListener વડે સાંભળો.
- ત્રણ callbacks: onTabSelected (અહીં કામ કરો, getPosition વડે), onTabUnselected, અને onTabReselected (ઉપર સુધી scroll કરવાની રૂઢિ).
- અભ્યાસક્રમનો ઢાંચો: tabs નક્કી કરે, FrameLayout બતાવે: સ્થાન પ્રમાણે કયું child દેખાય એ બદલો.
- શરૂઆતની visibility તમારે જાતે ગોઠવવી; મોટા પાયાની apps ViewPager2 તથા fragments પર ચડી જાય છે.
- યાદ રાખવાની કડી: પટ્ટી નક્કી કરે, frame બતાવે, અને છેલ્લું child સૌથી ઉપર.