• úvod
  • témata
  • události
  • tržiště
  • diskuze
  • nástěnka
  • přihlásit
    registrace
    ztracené heslo?
    LWEEKAndroid development
    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.
    DATEL
    DATEL --- ---
    Tak nakonec jsem to vyřešil trochu jinak. Vytvořil jsem si teda rozšiřující třídu pro Button, ikdyž by to šlo použít přímo ve fragmentu či kdekoliv, kde je dostupný objekt s tlačítkem, ale při více tlačítkách bych zbytečně opakoval kód, takže ta nová třída je jednodušší a použitelnější. Ve všech třech constructorech pak volám tuto metodu:

        private void setIcon() {
            float density = getResources().getDisplayMetrics().density;
            
            Drawable drawables[] = this.getCompoundDrawables();
            for (Drawable drawable : drawables ) {
                if (drawable != null) {
                    drawable.setBounds(0, 0, (int) (drawable.getIntrinsicWidth() / density), (int) (drawable.getIntrinsicHeight() / density));
                }
            }
            this.setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
        }
    
    DATEL
    DATEL --- ---
    DRIZDIK: díky za tip, ale nějak se mi nepodařilo dostat k tomu scaleType obrázku. V té rozšiřující třídě jsem si načetl drawable objekty:

    Drawable drawables[] = this.getCompoundDrawables();

    Jenže ten drawable objekt mi pak žádnou scaleType property ani set metodu nenabízí... Mohl bys mě prosím nasměrovat správným směrem? Díky.
    ZACK
    ZACK --- ---
    GORG: scene2d totalne ignoruju a to, co chces, delam pres BitmapFont.drawWrapped http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/BitmapFont.html

    Jinak zakladni povidani k bitmap fontu je tady: https://code.google.com/p/libgdx-users/wiki/addingText2D ... je to stary, ale co sem to tak prolit, tak platny.
    GORG
    GORG --- ---
    Našel jsem teď, jak k tomu dospět trošku těžkopádněji,ale samozřejmě asi by to snad mělo jít nějak implicitnějš ,)

    final float maxWidth = 2 * screenWidth/3;
    final float minWidth =Math.min(lblText.getTextBounds().width, maxWidth);

    this.add(lblText).fill().minWidth(minWidth).maxWidth(maxWidth);
    DRIZDIK
    DRIZDIK --- ---
    DATEL: Button je pouze TextView rozšířené o nastylování, takže to budeš schopen docílit jeho extendnutím a vnucením vlastního stylu a změníš scaleType u toho obrázku.
    GORG
    GORG --- ---
    https://code.google.com/p/table-layout/ tady je k tomu sice nějaké povídání, ale rád bych něco podrobnějšího, protože kolem toho mi zůstává stále mraky otazníků nejen v tomhle.
    Kliknutím sem můžete změnit nastavení reklam