• úvod
  • témata
  • události
  • tržiště
  • diskuze
  • nástěnka
  • přihlásit
    registrace
    ztracené heslo?
    LWEEKAndroid development
    Diskuse o vývoji aplikací pro platformu Android.
    -----------------
    Tipy, Triky, Postřehy, Začátečnický help, Nápady na nové aplikace.

    Oficiální developerská stránka: http://developer.android.com
    Něco málo v češtině na WiKi android fora: http://wiki.androidforum.cz/index.php/Programov%C3%A1n%C3%AD
    Článek na Zrojáku: http://zdrojak.root.cz/clanky/vyvoj-pro-android-ii/

    Docela zajímavé tutoriály přímo od vývojářů ze Sony Ericsson:

    na tvorbu vlastního View adapteru
    http://blogs.sonyericsson.com/developerworld/2010/05/20/android-tutorial-making-your-own-3d-list-part-1/

    zajímavý nápad na zoomování jedním prstem - aneb vytváření gest
    http://blogs.sonyericsson.com/developerworld/2010/05/18/android-one-finger-zoom-tutorial-part-1/
    rozbalit záhlaví
    DATEL
    DATEL --- ---
    VIRTUALVOID: aha... tak uvidím při testování, zatím se to chová normálně. Je teda fakt, že jednotlivé "sub" fragmenty v záložkách ukládám do seznamu a při jejich znovuvyvolání, pokud existují v tom seznamu, tak použiju tu existující instanci a jen nastavím argument s ID detailu, ale nijak jinak s tím nepracuju, tj. nijak je neschovávám nebo tak.

    VIRTUALVOID: to bych ti byl vděčný. Jestli jsem to dobře pochopil, tak ty používáš ActionBar, já mám ten starý TabHost, ale ono to bude myslím podobné, že?
    VIRTUALVOID
    VIRTUALVOID --- ---
    pomohol by som ti viac... ale zial mam tiez dost busy dni v praci.
    mozem ti poskytnut kusy zdrojaku nyxdroida kde riesim fragmenty v taboch.
    VIRTUALVOID
    VIRTUALVOID --- ---
    no, ako som pisal, ono je to stale o tom, ze nie vsetko to vyriesi. aktivita sa nebude znovu vytvarat (aspon nie na tvojej strane kodu), ale fragmenty budes musiet doriesit tiez.

    ja to napriklad robim tak, ze do kontajneru pridam vsetky fragmenty a tie ktore nepotrebujem aktualne aby boli viditelne ich schovam. potom v ActionBar.TabListener implementacii ich podla potreby (aktualny hide) zviditelnujem.
    preco ?
    pretoze pri replace(=remove,add) sa fragmenty vytvaraju nanovo. ked ich len hide/show tak nie.
    DATEL
    DATEL --- ---
    DATEL: tak v níže uvedeném odkaze jsem našel řešení, pro > 3.x nutno přidat ještě "screenSize".
    DATEL
    DATEL --- ---
    VIRTUALVOID: a kruci :( Tak jsem to zkusil v emulátoru pro verzi 4.0.3 a tam to nefunguje :( Fungovalo mi to ve 2.2
    DATEL
    DATEL --- ---
    VIRTUALVOID: JO! Jsi bůh!!! Díky. Jestli se někdy potkáme, máš u mě pivo - i víc klidně. Jen bych se k tomu ještě zeptal, co to vnitřně ovlivňuje? Našel jsem na SO tohle:

    Why not use always android:configChanges="keyboardHidden|orientation"? - Stack Overflow
    http://stackoverflow.com/...818717/why-not-use-always-androidconfigchanges-keyboardhiddenorientation

    a tam píše, že to není dobré mimo jiné pro fragmenty. Můžu očekávat nějaké problémy? Co jsem to zkusil v emulátoru, tak to všechno fungovalo.
    VIRTUALVOID
    VIRTUALVOID --- ---
    DRIZDIK: well, na to co potrebuje on to je podla mna dostacujuce. i ked ano, mas pravdu, nie korektne.
    DRIZDIK
    DRIZDIK --- ---
    VIRTUALVOID: to neni uplne stastny reseni .. potom musi vsechno resit sam, tim ukladanim stavu je to spravne a kdyz bude pouzivat spravne childFragmentManager, tak by si to toho mělo dost pamatovat i samo, pokud máš u těch fragmentů retain instance
    VIRTUALVOID
    VIRTUALVOID --- ---
    daj si do manifestu configChanges keyboard|keyboardHidden|orientation a aspon z casti ta znovu vytvaranie aktivity nemusi trapit
    DATEL
    DATEL --- ---
    Tak ty uložené fragmenty v savedInstaceState jsou parcelable, takže se dají vytáhnout přes

    Parcelable b = savedInstanceState.getParcelable("android:support:fragments");

    Ale je otázka, co s tím dál? Po rotaci se znovuvytváří aktivita, taby a základní fragmenty v tabech. Jediné, co mě napadá je si hlídat, jestli v tom seznamu je více než jeden fragment a pak na základě tagu vytvořit nový fragment příslušné třídy - jak mu ale podstrčit ten stav ze savedInstanceState? Nebo je to úplně nesmysl a má se to dělat jinak?
    DATEL
    DATEL --- ---
    VIRTUALVOID: ne, Fragmenty v Tabech řeším poprvé, s Androidem začínám. Použil jsem toto řešení: http://thepseudocoder.wordpress.com/2011/10/04/android-tabs-the-fragment-way/ jako základ. Jak jsem psal, některé taby jsou seznamy a ty můžou vyvolat fragment s detailem nebo fragment s dalším seznamem a ten zas fragment s detailem, to vše v rámci jedné záložky. Když se pak přepnu do jiného tabu, tak vymažu kompletně backstack v onTabChanged:

                while (this.getSupportFragmentManager().getBackStackEntryCount() > 0) {
                    this.getSupportFragmentManager().popBackStackImmediate();
                }
    


    a dále události v aktivitě, které nahrazují právě fragmenty v tabech, např.:

    public void onNewsItemClicked(long id) {
            Bundle args = new Bundle();
            args.putLong("id", id);
    
            TabInfo newTab = (TabInfo) this.mapTabInfo.get("TabNewsDetail");
            if (newTab == null) {
                newTab = new TabInfo("TabNewsDetail", NewsDetailFragment.class, args);
                this.mapTabInfo.put(newTab.tag, newTab);
            }
            
            if (newTab != null) {
                if (newTab.fragment == null) {
                    newTab.fragment = Fragment.instantiate(this, newTab.clss.getName(), args);
                } else {
                    newTab.fragment.setArguments(args);
                }
            }
            
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.realtabcontent, newTab.fragment, newTab.tag);
            ft.addToBackStack(null);
            ft.commit();
        }
    


    Ale zaboha nemůžu přijí na to, jak celý backstact obnovit :( V onCreate je v Bundle savedInstanceState v debuggeru vidět, že tam ty fragmenty jsou oba, ale nemám se jak na ně dostat, a ani když si dám vypsat nebo najít třeba ten fragments TabNewsDetail, tak to nic nenajde, zkoušel jsem různé:

    if (savedInstanceState != null) {
                mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state
                
                Log.d("MainActivity", "onCreate, keyset: " + savedInstanceState.keySet());
                
                /*FragmentManagerState b = savedInstanceState.get("android:support:fragments");
                Log.d("MainActivity", "onCreate, b: " + String.valueOf(b));*/
                
                Fragment f = this.getSupportFragmentManager().getFragment(savedInstanceState, "TabNewsDetail");
                //Fragment f = this.getSupportFragmentManager().findFragmentByTag("TabNewsDetail");
                Log.d("MainActivity", "onCreate, f: " + String.valueOf(f));
                
                int count = this.getSupportFragmentManager().getBackStackEntryCount(); 
                Log.d("MainActivity", "onCreate, entry count: " + String.valueOf(count));
                for (int i = 0; i < count; i++) {
                    BackStackEntry entry = this.getSupportFragmentManager().getBackStackEntryAt(i);
                    Log.d("MainActivity", "onCreate, entry class name: " + entry.getClass().getName());
                }
                
            }
    


    Dokonce je to tam uložené v nějaké třídě FragmentManagerState, která není známa, asi nějaká vnitřní privátní, ale ani vygooglit se mi ji nepovedlo.
    VIRTUALVOID
    VIRTUALVOID --- ---
    DATEL: neposielal som ti toto uz niekedy ? v nyxdroide to riesim...
    DATEL
    DATEL --- ---
    Prosím vás, implementoval jste někdo taby, ve kterých jsou fragmenty, přičemž některé taby jsou seznamy, které vedou na další fragment s detailem, případně tlačítko, které vede na jiný fragment seznam? Samo o sobě mi to celkem funguje (postup dle diskuzí na StackOverflow a jiných stránek), ale mám zásadní problém při změně orientace obrazovky - v té chvíli se zruší hlavní activita a všechny taby se vytrváří znova. Nedaří se mi vymyslet, jak po znovuvytvoření donutit aktuální tab, aby zobrazil třeba i ten detail. Na netu jsem taky pořádného nic nenašel. Jestli jste tohle někdo už řešil, tak se prosím ozvěte, nahodím kdyžtak podrobnosti, eventuelně kód. Díky moc.
    ROBUTEKK23
    ROBUTEKK23 --- ---
    ZACK: hm,.díkes za odpověď.. :D ale já mám internet banking, a chodí mi na mobil sms, a prej se to dá taky zneužít. moc tomu nerozumim,.
    ZACK
    ZACK --- ---
    Nejlepsi a dostatecny antivir pro jakykoliv android je nestahovat sracky z pochybnych stranek.
    ROBUTEKK23
    ROBUTEKK23 --- ---
    mám dotaz, jak je to s antivirem? který je nejlepší pro android 4?
    DATEL
    DATEL --- ---
    DATEL: DRIZDIK: Tak nakonec jsem použil řešení ze stack overflow, rozšířená třída Button s upravenou metodou onDraw(). Jen jsem tam opravil výpočet levé pozice ikonky:

        // ------------------------------------------------------------------------------------------
        // http://stackoverflow.com/a/15580164/2459448
    
        private Drawable mLeftDrawable;
        
        @Override
        //Overriden to work only with a left drawable.
        public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) {
            if (left == null) {
                return;
            }
            left.setBounds(0, 0, (int) (left.getIntrinsicWidth()), (int) (left.getIntrinsicHeight()));
            mLeftDrawable = left;
        }
        
        @Override
        protected void onDraw(Canvas canvas) {
            //transform the canvas so we can draw both image and text at center.
            canvas.save();
            canvas.translate(2 + (mLeftDrawable.getIntrinsicWidth()) / 2, 0);
            super.onDraw(canvas);
            canvas.restore();
            canvas.save();
            int widthOfText = (int) getPaint().measureText(getText().toString());
            //int left = (int) ((getWidth() + widthOfText) / 2 - (mLeftDrawable.getIntrinsicWidth()) - 2);
            int left = (int) ((getWidth() / 2) - (mLeftDrawable.getIntrinsicWidth() + widthOfText + 4) / 2);
            canvas.translate(left, (getHeight() - (mLeftDrawable.getIntrinsicHeight())) / 2);
            mLeftDrawable.draw(canvas);
            canvas.restore();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int height = getMeasuredHeight();
            height = Math.max(height, (int) ((mLeftDrawable.getIntrinsicHeight()) + getPaddingTop() + getPaddingBottom()));
            setMeasuredDimension(getMeasuredWidth(), height);
        }
    
    DRIZDIK
    DRIZDIK --- ---
    DATEL: často bude asi udělat ompozici z nějakejch view jednodušší než ohýbat jedno. Já s obrázkama taky zápasím a nemám to rád. :-/
    DATEL
    DATEL --- ---
    Teda ty tlačítka a obecně práce s obrázky v něčem je šílenost. Sice mi ta ikonka zachovává originální rozměry, ale je zarovnaná k okraji. Bohužel, aplikace je i pro API 8, takže zarovnání pomocí "start" (nevím teď, jak je to přesně, prostě by měl zarovnat na začátek textu tlačítka) nemůžu použít. Takže teď už opravdu asi jediná možnost jít tou cestou layoutu i image view a textview místo tlačítka - není to ale moc velká šílenost? Na druhou stranu, na Stack Overflow je toto řešení zmiňováno dost často.
    Kliknutím sem můžete změnit nastavení reklam