Wie viele Klassen und Layouts brauche ich für meine App?

N

no1Ltan

Fortgeschrittenes Mitglied
7
Hallo Leute,

bin ziemlich unerfahren im Bereich Android-Programmierung und brauche eure Hilfe.
Obwohl ich schon einige Fortschritte gemacht habe (Buttons mit Funktionen erstellen, designen etc.),
hänge ich grad bei diesem Thema fest:
Multiple Pages auf Android Wear.

Um es so einfach wie möglich zu erklären habe ich eine Skizze erstellt:
lh9fv5bd.png


Im Prinzip soll beim Starten der App nur die Ziffer und eine Farbe zu sehen sein.
Diese beiden Werte sollen dann mittels der 2. und 3. Seite verändert werden können.
(Durch Drücken der entsprechenden Buttons.)

Das Hin- und Herwechseln zwischen den Seiten soll mittels horizontalem Wischen erfolgen.
So, wie auf dieser Beispiel-Gif, nur ohne das vertikale Wischen und ohne die Punkte, die die Seite anzeigen.
1fdf7edd489bbf91.png


Kann ich mein Vorhaben mittels:
- 2 Java-Klassen (MainActivity.java, SectionFragment.java)
- 2 Layouts (activity_main.xml, fragment_section.xml)
realisieren?

Oder brauche ich in diesem Fall 3 Java-Klassen und 3 Layouts?
Beispielsweise:
- MainActivity.java, Colors_Activity.java, Values_Activity.java
- activity_main.xml, activity_colors.xml, activity_values.xml

Danke für jede Hilfe!
 
Hallo
Ich kenne mich mit Wear nicht aus.
Bei einem Handy macht man das mit Fragmenten die immer wieder ausgetauscht werden. Da zu kann man den Viewpager benutzen schaue mal ob es den bei wear auch gibt.
Es gibt dann nur eine activity und für jede angezeigte Seite ein Fragment . Ob es Viewpager bei Wear gibt weiss ich leider nicht aus dem Kopf.

Du brauchst 4 Klassen Main und 3 Fragmente. Dazu 4 Layouts .
 
Zuletzt bearbeitet:
Erstmal vielen Dank für deine Antwort.
Ich habe mich entschlossen, erstmal meine Basics zu verbessern und mich nur auf Smartphone zu konzentrieren.
Ein direkter Anfang mit Wear und solch einer App scheint wohl doch etwas zu viel... für den Anfang.
 
Hallo,

habe mich mal wieder mit dieser Thematik beschäftigt - allerdings nicht auf Wear sondern auf Mobile.
Vom Design und Handling her habe ich es dank Tutorials hinbekommen.
Man kann ganz normal hin- und herwischen.

Mein Problem ist derzeit allerdings, dass ich auf die Buttons, die sich auf View 2 befinden, nicht zugreifen kann.
Die Test-App besteht aus 4 Activities:
- MainActivity
- Page_1
- Page_2
- Page_3
und 5 layouts:
- activity_main.xml
- content_main.xml
- page1.xml
- page2.xml
- page3.xml

Beim Starten der App im Emulator kann ich wie schon erwähnt hin- und herswipen und sehe ganz klar die verschiedenen Views.
Wenn ich bei Page_2.java nun auf die Buttons zugreifen möchte, erscheint kein findViewById.
Es erscheint immer finalize() (als Vorschlag).
(Die Button-Klasse hatte ich selbstverständlich importiert.)

Ich las, dass man den Zugriff auf den Button unterhalb der inflater.inflate machen muss.
Auch das habe ich probiert, aber es ging nicht.
Hat jemand einen Rat, was ich bei Page_2.java hinzufügen muss, um auf Buttons zugreifen zu können?
Einen protected void onCreate(Bundle savedInstanceState) konnte ich nicht hinzufügen.

Die Codes in "Roh-Form":
MainActivity.java
Code:
package com.example.USER.clipcodes_swiping;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity
{
    ViewPager vp;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewPager vp = findViewById(R.id.vp);
        SetUpViewPager(vp);
    }
    public void SetUpViewPager(ViewPager viewpage)
    {
        MyViewPagerAdapter Adapter = new MyViewPagerAdapter(getSupportFragmentManager());
        Adapter.AddPageFragment(new Page_1(), "Page 1");
        Adapter.AddPageFragment(new Page_2(), "Page 2");
        Adapter.AddPageFragment(new Page_3(), "Page 3");
        viewpage.setAdapter(Adapter);
    }
    public class MyViewPagerAdapter extends FragmentPagerAdapter
    {
        private List<Fragment> MyFragment = new ArrayList<>();
        private List<String> MyPageTitle = new ArrayList<>();

        public MyViewPagerAdapter(FragmentManager manager)
        {
            super(manager);
        }
        public void AddPageFragment(Fragment Frag, String Title)
        {
            MyFragment.add(Frag);
            MyPageTitle.add(Title);
        }
        @Override
        public Fragment getItem(int i)
        {
            return MyFragment.get(i);
        }

        @Nullable
        @Override
        public CharSequence getPageTitle(int position)
        {
            return MyPageTitle.get(position);
        }

        @Override
        public int getCount()
        {
            return 3;
        }
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        int id = item.getItemId();

        if (id == R.id.action_settings)
        {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

Page_1.java (Das gleiche auch für Page_2.java und Page_3.java, nur eben mit 2, Two + Button-Klasse, 3, Three):
Code:
package com.example.USER.clipcodes_swiping;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Page_1 extends Fragment
{
    public Page_1(){} // Constructor
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View PageOne = inflater.inflate(R.layout.page1, container, false);
        return PageOne;
    }
}

activitiy_main.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

</android.support.design.widget.CoordinatorLayout>

content_main.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/vp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main"/>

page1.xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Page1"
    android:background="@color/brown">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="176dp"
        android:layout_marginTop="60dp"
        android:text="page1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

page2.xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:id="@+id/con_layout2"
    android:layout_height="match_parent"
    android:background="@color/red"
    android:text="Page2">

    <Button
        android:id="@+id/button_red"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        android:text="@string/button_red"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button_blue"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        android:text="@string/button_blue"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_red"
        app:layout_constraintVertical_bias="0.197" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="60dp"
        android:text="page2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.501"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

page3.xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Page3"
    android:background="@color/yellow">

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="172dp"
        android:layout_marginTop="60dp"
        android:text="page3"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

Danke für jede Hilfe!
 
In Fragments musst du das in der onCreateView auf der View machen, also:

Code:
public class Page_1 extends Fragment
{
   public Page_1(){} // Constructor
   @Nullable
   @Override
   public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
   {
       View PageOne = inflater.inflate(R.layout.page1, container, false);
       Button button = (Button)PageOne.findViewById(....)
       return PageOne;
   }
}

Kleine Hinweise zum Code Style (per Java Konvention):
- einen leeren Konstruktor musst du nicht definieren, der ist immer da
- Klassennamen sollten keinen Unterstrich enthalten Page_1 -> Page1, besser sogar einen beschreibenden Namen verwenden, falls die Reihenfolge später mal geändert wird. Sowas wie IntroPage vielleicht (je nach Zweck der Seite)
- Variablennamen sollten mit Kleinbuchstaben anfangen.
- In Packagenamen auch keine Unterstriche, diese komplett klein halten, wenn erfordert einen weiteren Punkt dazu
 
  • Danke
Reaktionen: no1Ltan
Ergänzen möchte ich noch das du auch die Activity benutzen kannst.

Button button = (Button) getActivity().findViewById(....);
button..setOnClickListener(this);

kannst dir den Context auch in einer Variablen speichern.
Activity myActivity;
myActivity = getActivity();

In der onAttach(Activity activity) bekommst du auch die Activity übergeben.

@override
public void onAttach(Activity activity) {
super.onAttach(activity);
myActivity = activity;
}


Somit bist du flexibler mit dem findViewById und nicht auf die onCreateView angewiesen.
 
  • Danke
Reaktionen: no1Ltan
getActivity ist aber gefährlich, gerade mit einem ViewPager. (gefährlich im Sinne von kann null zurückgeben)
Ich würde um auf Views zuzugreifen, die sowieso im Fragment Layout sind lieber darauf verzichten, da ist die sicherere Methode onCreateView.
Wenn man den ViewPager mal etwas umbaut auf lazy loading kann der munter Fragmente bauen und zerstören, oder im Speicher halten wenn die Activity destroyed wird (Bildschirm drehen) und schwupps hast du gerade entweder gar keine oder die falsche (alte) Activity in der Hand.
 
  • Danke
Reaktionen: no1Ltan
Beim drehen des Handys ändert sich doch nicht die activity. Mit onAttach sollte aber die richtige activity übergeben werden.

Ok auch da kann es Probleme geben wenn nur die view zerstört wird wird onAttach nicht durchlaufen.
Danke für den Hinweis.
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: no1Ltan
Hallo,

erstmal ein großes Danke für euren Support!

Bezüglich der Codes in meinem Post muss ich ehrlich zugeben, dass ich dieses Beispiel mittels eines Tutorials nachgestellt habe.
Normalerweise schreibe ich Variablennamen immer im Camel Case, z.B. buttonRed.
Ebenso würde ich natürlich nie Page_1.java, Page_2.java etc. verwenden,
sondern eher SettingsActivity.java, ColorsActivity.java usw.
Ich muss zugeben, dass ich das mit Page_1.java und dann PageOne echt verwirrend finde.
Allerdings würde ich ausnahmsweise in diesem App-Beispiel so lassen.
Soweit ich aber weiß, soll man die Unterstriche bei ids verwenden, z.B. button_red.

Dass man leere Konstruktoren nicht definieren muss, wusste ich nicht - hatte ich in einem Lernvideo gesehen.
Vielleicht liegt das ja an der neueren Android Studio Version?

Jedenfalls habe ich wieder gute Fortschritte gemacht!
Die Buttons der "Page_2" ändern die Hintergrundfarbe und Textfarbe von Page_1.
Das einzige Problem ist, dass ich die Änderung erst sehe, wenn ich von Page_2 auf Page_3 wechsele
und danach auf Page_2 und Page_1.
Beim direkten Wechsel von Page_2 auf 1 (nachdem ich geklickt habe), ändert sich nichts.

Das sind die Codes, die ich modifiziert habe:
Hab auch Kommentare hinzugefügt, damit man sieht, ob ich die Codezeilen auch tatsächlich verstanden habe.
Page_1.java

Code:
package com.example.USER.clipcodes_swiping;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.constraint.ConstraintLayout;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import static android.content.Context.MODE_PRIVATE;

public class Page_1 extends Fragment
{
    int colorNumber, textColor; // Variables for SharedPreferences
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View PageOne = inflater.inflate(R.layout.page1, container, false); // Link view to layout?
        SharedPreferences prefs = getActivity().getSharedPreferences("bgColor", MODE_PRIVATE); // Load saved shared file
        colorNumber = prefs.getInt("color", colorNumber); // Load saved background color
        textColor = prefs.getInt("tcolor", textColor); // Load saved text color
        ConstraintLayout conLayout1 = PageOne.findViewById(R.id.con_layout1); // Link variable to ID
        conLayout1.setBackgroundColor(colorNumber); // Change background color
        TextView tv1 = PageOne.findViewById(R.id.tv_1); // Link variable to ID
        tv1.setTextColor(textColor); // Change text color
        return PageOne;
    }
}

Page_2.java
Code:
package com.example.USER.clipcodes_swiping;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import static android.content.Context.MODE_PRIVATE;

public class Page_2 extends Fragment
{
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View PageTwo = inflater.inflate(R.layout.page2, container, false);
        Button buttonRed = PageTwo.findViewById(R.id.button_red);  // Link variable to ID
        buttonRed.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                setColor(getResources().getColor(R.color.red), getResources().getColor(R.color.white)); // Load setColor method and send 2 color values
            }
        });
        Button buttonBlue = PageTwo.findViewById(R.id.button_blue);  // Link variable to ID
        buttonBlue.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                setColor(getResources().getColor(R.color.blue), getResources().getColor(R.color.black)); // Load setColor method and send 2 color values
            }
        });
        return PageTwo;
    }
    public void setColor (int colorNumber, int textColor) // Write color values into SharedPreferences
    {
        Intent intentColor = new Intent(getActivity(), Page_1.class); // Create intent for current Activity and target activity
        SharedPreferences prefs = getActivity().getSharedPreferences("bgColor", MODE_PRIVATE); // Create new SharedPreferences instance
        SharedPreferences.Editor editor = prefs.edit(); // Assign variable to editor function
        editor.putInt("color", colorNumber); // Write background color (int) inside of editor
        editor.putInt("tcolor", textColor); // Write text color (int) inside of editor
        editor.commit(); // Save values, close process
    }
}

Achso, eine kleine Unklarheit habe ich dennoch:
Ich dachte ursprünglich, dass die MainActivity die 1.Seite der App wäre.
Aber anscheinend sorgt sie "nur" dafür, dass die 3 Seiten miteinander kommunizieren und verbunden sind.
Der Benutzer arbeitet also nicht direkt mit der MainActivity, so wie man das bei einer 1-Seitigen App kennt.
Habe ich das richtig erfasst?

Viele Grüße
 
Hi also ich führe änderungen am layout wie settext usw. nicht in der onCreateView aus .
Sondern in der onActivityCreated aus. Kannst du als die onCreate des Fragments ansehen.
Zu dem Zeitpunkt ist auch das layout schon geladen.
Der Pager wird sich wohl beim Swype von 1 zu 2 die View auf den Backstack laden. Um schnell wieder zurück gehen zu können. Dabei wird die View nicht neu geladen. Wenn er ein weiter Seite geladen hat ist der Backstack wohl veraltet und die View wird neu geladen.

die Methode onActivityCreated sollte aber ausgeführt werden. Kannst es ja mit ein paar Logs verfolgen.


Zu deinem Code was machst du eigentlich mit dem Intent? Denn kannst du nicht auf ein Fragment anwenden.
Ein Fragment wird sozusagen in der activity ausgeführt und das layout des Fragment wird mit dem layout der Activity getauscht. Die activity wird dabei nicht beendet die läuft die ganze Zeit.

Zu deiner kleinen Unklarheit, ja so kann man es sehen. Ein fragment kann nicht alleine laufen es braucht immer eine activity.
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: no1Ltan
Hi,
ok, aber ich brauche dennoch die onCreateView, oder?
Weil wenn ich es nur mit der onActivityCreated versuche, kennt er die inflater nicht.
Ich kann leider nur schwer einschätzen, ob ich mit dem Code knapp daneben liege
oder ob's viele Fehler gibt.
Hab auf jeden Fall gelesen, dass die Reihenfolge onCreate -> onCreateView -> onActivityCreated sein soll/muss.
(Eine onCreate gibt's bei mir im eigentlichen Sinne ja nicht - nur in der mainActivity.java.)

P.S: Den Intent hab ich auf Page_2 rausgeschmissen. Hattest Recht, der hatte keinen Effekt.

c8fh6sfq.png
 
Ok, habe jetzt 2 Zeilen verändert:

In der onActivityCreated:
Code:
        ConstraintLayout conLayout1 = getActivity().findViewById(R.id.con_layout1); // Link variable to ID
        conLayout1.setBackgroundColor(colorNumber); // Change background color
        TextView tv1 = getActivity().findViewById(R.id.tv_1); // Link variable to ID

Ob es wirklich richtig ist, weiß ich nicht, aber der Fehler ist weg und die App läuft jetzt.
Allerdings wird der Hintergrund von View1 trotzdem erst verändert, wenn ich auf Page3 gewesen bin.

Viele Grüße
 
Hallo habe es mal getestet.

Der Viewpager lädt im Hindergund schon das fragment vor um es schneller anzeigen zu können. Das macht er immer und zwar die beiden benachbarten Fragments . Wenn du von 1 zu 2 gehst wird das schon vorgeladene 2 angezeigt und er lädt 3 und 2 wenn notwendig vor. Wenn du nun klickst wird und zurück zu 1 gehst wird nichtst neu geladen auch nicht onActivityCreated , onResume …

Habe das mit Log getestet.

Ich habe nun den Code so verändert das wenn Frag 1 angezeigt wird die onResume aufgerufen wird.

Code:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener
{
    ViewPager vp;
    MyViewPagerAdapter Adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewPager vp = findViewById(R.id.vp);
        SetUpViewPager(vp);
    }
    public void SetUpViewPager(ViewPager viewpage)
    {
        Adapter = new MyViewPagerAdapter(getSupportFragmentManager());
        Adapter.AddPageFragment(new Page_1(), "Page 1");
        Adapter.AddPageFragment(new Page_2(), "Page 2");
        Adapter.AddPageFragment(new Page_3(), "Page 3");
        viewpage.setAdapter(Adapter);
        viewpage.addOnPageChangeListener(this);
    }


    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {

        Fragment fragment = Adapter.getFragment(position);

        if (fragment != null) {
            fragment.onResume();
        }

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    //-------------------------------------------------------------------------------
    public class MyViewPagerAdapter extends FragmentPagerAdapter {
        private List<Fragment> MyFragment = new ArrayList<>();
        private List<String> MyPageTitle = new ArrayList<>();

        private Map<Integer, String> mFragmentTags;
        private FragmentManager mFragmentManager;


        public MyViewPagerAdapter(FragmentManager manager) {
            super(manager);
            mFragmentManager = manager;
            mFragmentTags = new HashMap<Integer, String>();

        }


        public void AddPageFragment(Fragment Frag, String Title) {
            MyFragment.add(Frag);
            MyPageTitle.add(Title);
        }

        @Override
        public Fragment getItem(int i) {
            switch (i) {
                case 0:
                    return Page_1.newInstance();

                default:
                    return MyFragment.get(i);
            }
        }

        @Nullable
        @Override
        public CharSequence getPageTitle(int position) {

            return MyPageTitle.get(position);
        }

        @Override
        public int getCount() {
            return 3;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Object object = super.instantiateItem(container, position);
            if (object instanceof Fragment) {
                Fragment fragment = (Fragment) object;
                String tag = fragment.getTag();
                mFragmentTags.put(position, tag);
            }
            return object;
        }

        public Fragment getFragment ( int position){
            Fragment fragment = null;
            String tag = mFragmentTags.get(position);
            if (tag != null) {
                fragment = mFragmentManager.findFragmentByTag(tag);
            }
            return fragment;
        }

    }
    // -----------------------------------------------------------------------------------

    /*@Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        int id = item.getItemId();

        if (id == R.id.action_settings)
        {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }*/
}

Code:
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.constraint.ConstraintLayout;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import static android.content.Context.MODE_PRIVATE;

public class Page_1 extends Fragment
{
    int colorNumber, textColor; // Variables for SharedPreferences
    ConstraintLayout conLayout1;
    TextView tv1;
    public static Page_1 newInstance() {

              return new Page_1();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        Log.v( "test","Page 1 onCreateView" );
        View PageOne = inflater.inflate(R.layout.page1, container, false); // Link view to layout?
        conLayout1 = PageOne.findViewById(R.id.con_layout1); // Link variable to ID
        tv1 = PageOne.findViewById(R.id.tv_1); // Link variable to ID
        return PageOne;
    }

     @Override
    public void onResume() {
        super.onResume();
        Log.v( "test","Page 1 onResume" );
        SharedPreferences prefs = getActivity().getSharedPreferences("bgColor", MODE_PRIVATE); // Load saved shared file
        colorNumber = prefs.getInt("color", colorNumber); // Load saved background color
        textColor = prefs.getInt("tcolor", textColor); // Load saved text color
        conLayout1.setBackgroundColor(colorNumber); // Change background color
        tv1.setTextColor(textColor); // Change text color

    }
}
 
Hallo, hatte gerade eine Idee.
Ich könnte mit dem Button auf Page2 doch sowohl die SharedPreferences beschreiben als auch direkt die Farbe des Layouts von Page1 festlegen.
Dann wird
a) die Farbe gespeichert
b) sofort der Hintergrund geändert.

Es funktioniert:

Code:
    public void setColor (int colorNumber, int textColor) // Write color values into SharedPreferences
    {
        SharedPreferences prefs = getActivity().getSharedPreferences("bgColor", MODE_PRIVATE); // Create new SharedPreferences instance
        SharedPreferences.Editor editor = prefs.edit(); // Assign variable to editor function
        editor.putInt("color", colorNumber); // Write background color (int) inside of editor
        editor.putInt("tcolor", textColor); // Write text color (int) inside of editor
        editor.commit(); // Save values, close process
        ConstraintLayout conLayout1 = getActivity().findViewById(R.id.con_layout1); // Link variable to ID
        conLayout1.setBackgroundColor(colorNumber); // Change background color
    }

Ob es allerdings "sauber" ist, kann ich nicht wissen.
Da kommst du ins Spiel ;)

Grüße
 
Das geht zwar weil er das Fragment vorgeladen hat. Aber wenn er es mal nicht hat , in dem du das Handy drehst, ist das Layout nicht geladen und du bekommst bei findviewbyid einen Fehler. NullPointer.
 
Ich habe gelesen, dass man FrameLayouts verwenden soll, wenn man Fragmente austauschen will.
Allerdings glaube ich, dass das bei meiner App nicht der Fall ist, da ich die Fragmente ja mittels hin- und herwischen wechsele.

Ich habe übrigens eine 4. Page erzeugt, die Buttons beinhaltet.
Von der 2. Page springe ich mittels eines Intents (per Buttonklick) auf die 4. Page, da diese kein Fragment sondern eine Activity ist.
Das klappt soweit.
 
Ob du ein Frame layout oder ein anderes benutzt spielt keine Rolle. Es ändert nichts an der Tatsache wie der viewpager die Fragmente lädt.
[doublepost=1534737118,1534735490][/doublepost]Das mit den framelayout wird in vielen toturial so beschreiben. Daist so in dem Layout der activity brauchst du ein Layout in dem eigentlich nichts ist das dient nur als Container. Da nun das Framelyout das einfachste Layout ist wird dies bei den Tutorial favorisiert.
In diesen Container werden dann später zur Laufzeit die Layouts der Fragment Klassen geladen und angezeigt.
Dies wird mit hilfe des Fragmentmanager und einer Transaktion gemacht.
Beim Viewpager brauchst du dich nicht darum zu kümmern der macht das alles für dich.

Welches Layout er als Container benutz weiß man nicht ist auch nicht wichtig.

Du hast in deinem Main Layout doch mittels der include Anweisung die zweite Datei mit dem Viewpager in dein Layout eingebunden. Und das stellt deinen Container dar.

So ich denke das reicht erstmal.
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: no1Ltan
Habe mir jetzt noch mal die Doku vom Viewpager angesehen , und dies gefunden.

ViewPager | Android Developers
setOffscreenPageLimit
added in version 22.1.0
void setOffscreenPageLimit (int limit)
Set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state. Pages beyond this limit will be recreated from the adapter when needed.

This is offered as an optimization. If you know in advance the number of pages you will need to support or have lazy-loading mechanisms in place on your pages, tweaking this setting can have benefits in perceived smoothness of paging animations and interaction. If you have a small number of pages (3-4) that you can keep active all at once, less time will be spent in layout for newly created view subtrees as the user pages back and forth.

You should keep this limit low, especially if your pages have complex layouts. This setting defaults to 1.

Wenn du nun "mViewPager.setOffscreenPageLimit(0);" beim erstellen des Pagers benutzt lädt er keine Seiten mehr vor. es Wird also immer die onCreatView durchlaufen. Dies solte dein Problem auf einer sauberen und einfachen art lösen.
 
  • Danke
Reaktionen: no1Ltan
Hallo,

Danke für die Information - das klingt vielversprechend.
Habe es mal versucht, allerdings hat sich nichts geändert.
In einem anderen Forum habe ich gelesen, dass der Minimum-Wert 1 sein muss.

Vielleicht habe ich es aber auch falsch gecodet.
MainActivity.java

Code:
public class MainActivity extends AppCompatActivity
{
    ViewPager vp;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewPager vp = findViewById(R.id.vp);
        SetUpViewPager(vp);
    }
    public void SetUpViewPager(ViewPager viewpage)
    {
        MyViewPagerAdapter Adapter = new MyViewPagerAdapter(getSupportFragmentManager());
        Adapter.AddPageFragment(new Page_1(), "Page 1");
        Adapter.AddPageFragment(new Page_2(), "Page 2");
        Adapter.AddPageFragment(new Page_3(), "Page 3");
        viewpage.setOffscreenPageLimit(0);
        viewpage.setAdapter(Adapter);
    }
.
.
.
(Der Rest ist gleich geblieben).

Habe jetzt aber ein anderes Problem - unabhängig von dieser Thematik.

In der 1. Page habe ich einen 2. Hintergrund erstellt.
Page 2 verfügt über 2 Buttons, die für die Hintergründe von Page1 verantwortlich sind.
Beim Klick auf einen der beiden Buttons auf Page 2, wird eine neue Activity gestartet,
die aus vielen Farb-Buttons besteht.

Beim Klick auf einen der Farb-Buttons wird die Activity geschlossen und die Hintergründe von Page 1
nehmen die korrekte Farbe an.
(Klicke ich nur auf den linken, ändert sich die Farbe des linken Hintergrunds und die Farbe des rechten bleibt unangetastet.)

Es funktioniert, aber komischerweise geht es nur noch über die SharedPreferences, nicht mehr in dem ich
direkt die Farben der layouts beschreibe.
(Die IDs sind auch korrekt.)

Code von Page2 (2 Buttons, die jeweils die Farbe vom linken oder rechten Hintergrund ändern):

Code:
package com.example.USER.clipcodes_swiping;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;

import static android.content.Context.MODE_PRIVATE;

public class Page_2 extends Fragment
{
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View PageTwo = inflater.inflate(R.layout.page2, container, false);
        Button buttonLeft = PageTwo.findViewById(R.id.button_left);  // Link variable to ID of left button
        buttonLeft.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                int pos = 1; // Set position to left
                setColor(pos); // Load setColor method and send 2 color values
            }
        });
        Button buttonRight = PageTwo.findViewById(R.id.button_right);  // Link variable to ID of right button
        buttonRight.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                int pos = 2; // Set position to right
                setColor(pos); // Load setColor method and send 2 color values
            }
        });
        return PageTwo;
    }
    public void setColor (int pos) // Write color values into SharedPreferences
    {
        Intent intentPos = new Intent(getActivity(), Page_4_Colors.class); // Create intent for current Activity and target activity
        SharedPreferences prefs = getActivity().getSharedPreferences("bgColor", MODE_PRIVATE); // Create new SharedPreferences instance
        SharedPreferences.Editor editor = prefs.edit(); // Assign variable to editor function
        editor.putInt("position", pos); // Write background color (int) inside of editor
        editor.commit(); // Save values, close process
        getActivity().startActivity(intentPos);
    }
}

Code von Page4:
Code:
package com.example.USER.clipcodes_swiping;

import android.app.Activity;
import android.content.SharedPreferences;
import android.graphics.pdf.PdfDocument;
import android.os.Bundle;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import static android.content.Context.MODE_PRIVATE;

public class Page_4_Colors extends Activity
{
    int pos;
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.page4_colors);
        SharedPreferences prefs = getSharedPreferences("bgColor", MODE_PRIVATE); // Load saved shared file
        pos = prefs.getInt("position", pos); // Load saved background color
        Log.wtf("Position", String.valueOf(pos)); // Show pos value in Log
        Button buttonWhite = findViewById(R.id.button_white);
        buttonWhite.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                setColor(getResources().getColor(R.color.white), getResources().getColor(R.color.black)); // Load setColor method and send 2 color values
            }
        });
        Button buttonYellow = findViewById(R.id.button_yellow);
        buttonYellow.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                setColor(getResources().getColor(R.color.yellow), getResources().getColor(R.color.black)); // Load setColor method and send 2 color values
            }
        });
        Button buttonOrange = findViewById(R.id.button_orange);
        buttonOrange.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                setColor(getResources().getColor(R.color.orange), getResources().getColor(R.color.black)); // Load setColor method and send 2 color values
            }
        });
        Button buttonRed = findViewById(R.id.button_red);
        buttonRed.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                setColor(getResources().getColor(R.color.red), getResources().getColor(R.color.black)); // Load setColor method and send 2 color values
            }
        });
        Button buttonGreen = findViewById(R.id.button_green);
        buttonGreen.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                setColor(getResources().getColor(R.color.green), getResources().getColor(R.color.black)); // Load setColor method and send 2 color values
            }
        });
        Button buttonBlue = findViewById(R.id.button_blue);
        buttonBlue.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                setColor(getResources().getColor(R.color.blue), getResources().getColor(R.color.white)); // Load setColor method and send 2 color values
            }
        });
    }
    public void setColor (int backgroundColor, int textColor) // Write color values into SharedPreferences
    {
        SharedPreferences prefs = getSharedPreferences("bgColor", MODE_PRIVATE); // Create new SharedPreferences instance
        SharedPreferences.Editor editor = prefs.edit(); // Assign variable to editor function
        if (pos == 1) // If left button was clicked
        {
            editor.putInt("backgroundColorLeft", backgroundColor); // Write background color (int) inside of editor
            editor.putInt("textColorLeft", textColor); // Write text color (int) inside of editor
/*            RelativeLayout relLayoutLeft = findViewById(R.id.rel_layout_left); // Link variable to ID of left background
            relLayoutLeft.setBackgroundColor(backgroundColor); // Change background color of left side
            TextView tvLeft = findViewById(R.id.tv_left); // Link variable to ID of left text
            tvLeft.setTextColor(textColor); // Change text color of left side*/
        }
        if (pos == 2) // If right button was clicked
        {
            editor.putInt("backgroundColorRight", backgroundColor); // Write background color (int) inside of editor
            editor.putInt("textColorRight", textColor); // Write text color (int) inside of editor
/*            RelativeLayout relLayoutRight = findViewById(R.id.rel_layout_right); // Link variable to ID of right background
            relLayoutRight.setBackgroundColor(backgroundColor); // Change background color of Right side
            TextView tvRight = findViewById(R.id.tv_right); // Link variable to ID of Right text
            tvRight.setTextColor(textColor); // Change text color of Right side*/
        }
        editor.commit(); // Save values, close process
        this.finish(); // Close this activity
    }
}

Sobald ich auf Page4 die 4 Codezeilen (in beiden if-Statements) wieder einkommentiere, funktioniert es nicht.
Vorher ging es aber.
Die App stürzt immer ab, sobald ich auf einen Farb-Button in Page4 klicke.
So läuft es übrigens, wenn die Zeilen auskommentiert sind (nur um es verständlicher zu machen)
ztyx8zaw.gif


Edit:
Komischerweise wurden die Anhänge hochgeladen, obwohl nie 100% erreicht wurden.

Viele Grüße
 

Anhänge

  • AndroidApp.gif
    AndroidApp.gif
    1,2 MB · Aufrufe: 319
Hi werde es mir morgen anschauen. Am Handy geht das nicht so gut.
 

Ähnliche Themen

M
Antworten
3
Aufrufe
167
moin
M
netfreak
  • netfreak
Antworten
10
Aufrufe
457
netfreak
netfreak
Manny87
  • Manny87
Antworten
11
Aufrufe
166
swa00
swa00
Zurück
Oben Unten