Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
speng31b
May 8, 2010

hooah posted:

Ok, I guess I kinda glossed over the Object thing and assumed that meant JSONObject.

I'm using Android Studio for the app, this is just an exercise, so by "I'm lazy" I meant "I don't feel like figuring out right now how to set up a dummy class", since they just provide that in the online IDE.

When you find things don't compile, your best bet is to more than casually glance at the documentation.

Adbot
ADBOT LOVES YOU

hooah
Feb 6, 2006
WTF?
I think my problem was I'm not used to seeing the return information and the rest of the signature visually separated like they are near the top of the documentation. At least, that's the only excuse I can think of. I swear, I'll get better at reading documentation, it's just not a thing I've had to do much so far over 1.5 years of CSE courses.

fritz
Jul 26, 2003

I'm trying to understand ListFragment and updating the contents dynamically. I have a couple classes that I pulled from a tutorial I found:
code:
package com.example.lx1;

import android.app.Activity;
import android.app.FragmentManager;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity {
    SimpleListFragment list = new SimpleListFragment();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        FragmentManager fm = getFragmentManager();
        if (fm.findFragmentById(android.R.id.content) == null) {
            fm.beginTransaction().add(android.R.id.content, list).commit();
        }
        list.set_text(new String[] {"A", "B", "C"});

        if (list.adapter != null) {
            list.adapter.notifyDataSetChanged();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        list.set_text(new String[] {"A", "B", "C"});
        if (list.adapter != null) {
            list.adapter.notifyDataSetChanged();
        } else {
            Log.e("LX1", "null adapter");
        }
    }
}
code:
package com.example.lx1;

import android.app.ListFragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;


public  class SimpleListFragment extends ListFragment
{
    public void set_text(String[] numbers_text) {
        Log.d("SLF", "set_text entered!");
        this.numbers_text = numbers_text;
        this.numbers_digits = new String[numbers_text.length];
        for(int i=0; i < numbers_text.length; i++) {
            this.numbers_digits[i] = Integer.toString(i+1);
        }
    }

    String[] numbers_text = new String[] { "one", "two", "three", "four",
            "five", "six", "seven", "eight", "nine", "ten", "eleven",
            "twelve", "thirteen", "fourteen", "fifteen" };
    String[] numbers_digits = new String[] { "1", "2", "3", "4", "5", "6", "7",
            "8", "9", "10", "11", "12", "13", "14", "15" };

    public ArrayAdapter<String> adapter = null;

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        Log.d("SLF", numbers_digits[(int)id]);
        Toast.makeText(getActivity(), numbers_digits[(int) id], Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        adapter = new ArrayAdapter<String>(getActivity(),
                    android.R.layout.simple_list_item_1,
                numbers_text);
        setListAdapter(adapter);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }
}
When I start up the program initially, I get A/B/C, but when I do things like rotate the device I get the One/Two/Three/...etc. So somehow the numbers_text is getting re-set, but my mental model isn't good enough to tell me what's going on.

(What I want, eventually, is to have an interface where I have two lists of objects, determined at run time and possibly changing, and a way to associate one with the other)

fritz fucked around with this message at 19:05 on Dec 18, 2014

speng31b
May 8, 2010

fritz posted:

I'm trying to understand ListFragment and updating the contents dynamically. I have a couple classes that I pulled from a tutorial I found:

When I start up the program initially, I get A/B/C, but when I do things like rotate the device I get the One/Two/Three/...etc. So somehow the numbers_text is getting re-set, but my mental model isn't good enough to tell me what's going on.

(What I want, eventually, is to have an interface where I have two lists of objects, determined at run time and possibly changing, and a way to associate one with the other)

You're calling methods on an unused List fragment after rotation because you're creating a new Fragment for each Activity but not using it. You need to reuse the existing Fragment if it's found instead of creating a new one for each Activity. Your MainActivity should look something like this:

code:
public class MainActivity extends Activity {
    SimpleListFragment list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        FragmentManager fm = getFragmentManager();
        list = fm.findFragmentById(android.R.id.content);
        if (list == null) {
            list = new SimpleListFragment();
            fm.beginTransaction().add(android.R.id.content, list).commit();
        }
        list.set_text(new String[] {"A", "B", "C"});

        if (list.adapter != null) {
            list.adapter.notifyDataSetChanged();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        list.set_text(new String[] {"A", "B", "C"});
        if (list.adapter != null) {
            list.adapter.notifyDataSetChanged();
        } else {
            Log.e("LX1", "null adapter");
        }
    }
}

fritz
Jul 26, 2003

speng31b posted:

You're calling methods on an unused List fragment after rotation because you're creating a new Fragment for each Activity but not using it. You need to reuse the existing Fragment if it's found instead of creating a new one for each Activity. Your MainActivity should look something like this:


OK, I changed it to
code:
public class MainActivity extends Activity {
    SimpleListFragment list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FragmentManager fm = getFragmentManager();
        list = (SimpleListFragment)fm.findFragmentById(android.R.id.content);
        if (list == null) {
            Log.d("LX1", "creating new SimpleListFragment");
            list = new SimpleListFragment();
            fm.beginTransaction().add(android.R.id.content, list).commit();
        }
        list.set_text(new String[] {"A", "B", "C"});

        if (list.adapter != null) {
            list.adapter.notifyDataSetChanged();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        list.set_text(new String[] {"A", "B", "C"});
        if (list.adapter != null) {
            list.adapter.notifyDataSetChanged();
        } else {
            Log.e("LX1", "null adapter");
        }
    }
}
but I'm still seeing the same thing.

Also one thing I just noticed is when it goes to the One/Two/... state, if I click on "Four" or higher, I get a java.lang.ArrayIndexOutOfBoundsException, which suggests that numbers_text has been changed but numbers_digits has not. I also noticed that set_text is getting called twice every time I rotate the device somehow.

I added some logging statements:
code:

public  class SimpleListFragment extends ListFragment
{
    public void set_text(String[] numbers_text) {
        Log.d("SLF", "set_text entered with " + Integer.toString(numbers_text.length) + " items");
        this.numbers_text = numbers_text;
        this.numbers_digits = new String[numbers_text.length];
        for(int i=0; i < numbers_text.length; i++) {
            this.numbers_digits[i] = Integer.toString(i+1);
        }

        assert this.numbers_digits.length == this.numbers_text.length;
    }

    String[] numbers_text = new String[] { "one", "two", "three", "four",
            "five", "six", "seven", "eight", "nine", "ten", "eleven",
            "twelve", "thirteen", "fourteen", "fifteen" };
    String[] numbers_digits = new String[] { "1", "2", "3", "4", "5", "6", "7",
            "8", "9", "10", "11", "12", "13", "14", "15" };

    public ArrayAdapter<String> adapter = null;

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        Log.d("SLF", "There are " + Integer.toString(adapter.getCount()) + " things in the adapter");
        Log.d("SLF", "The sources have " + Integer.toString(numbers_digits.length) + " and " + Integer.toString(numbers_text.length) + " elements");
        Log.d("SLF", "Selected " + numbers_digits[(int)id]);
        Toast.makeText(getActivity(), numbers_digits[(int) id], Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        assert this.numbers_digits.length == this.numbers_text.length;

        adapter = new ArrayAdapter<String>(getActivity(),
                    android.R.layout.simple_list_item_1,
                    numbers_text);
        setListAdapter(adapter);
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        assert this.numbers_digits.length == this.numbers_text.length;

        return super.onCreateView(inflater, container, savedInstanceState);
    }
}
And after a rotation, adapter.getCount() goes from 3 to 15.

fritz
Jul 26, 2003

One thing that seems to work is forcing a new adapter to be created:

code:

    public void set_text(String[] numbers_text) {
        Log.d("SLF", "set_text entered with " + Integer.toString(numbers_text.length) + " items");

        this.numbers_text = numbers_text;
        this.numbers_digits = new String[numbers_text.length];
        for(int i=0; i < numbers_text.length; i++) {
            this.numbers_digits[i] = Integer.toString(i+1);
        }
        if (adapter != null) {
            adapter = new ArrayAdapter<String>(getActivity(),
                    android.R.layout.simple_list_item_1,
                    numbers_text);
            setListAdapter(adapter);
        }
        assert this.numbers_digits.length == this.numbers_text.length;
    }
But that doesn't really feel like a "correct" solution.

speng31b
May 8, 2010

You have to call notifyDataSetChanged on the adapter whenever you change its underlying data unless you want to create a new adapter every time. Alternatively you modify the adapter's data set by calling methods on the adapter rather than directly modifying the underlying data, and then the adapter will automatically take care of notifying everything.

Basically, adapters give you the freedom to modify the underlying data set manually for more complex changes and then notify that something has changed. For simple operations it's better to work through the adapter's methods to avoid accidentally forgetting to notify the adapter. If you don't notify it, it has no simple way of detecting that something has changed - this isn't iOS crazyland where you can observe arbitrary value changes on an Object (http://www.appcoda.com/understanding-key-value-observing-coding/).

speng31b fucked around with this message at 20:32 on Dec 18, 2014

PiCroft
Jun 11, 2010

I'm sorry, did I break all your shit? I didn't know it was yours

Does anyone else struggle with Android tools? I've done both iOS and Android, and I coped well with both but by far the worst thing I've experienced in my career as a software developer is android tools. All the IDEs for android that I've tried, including Eclipse and Android Studio are a nightmare to get working with a mature project and getting a project with multiple modules working with Gradle was a headache. Does anyone else struggle with the tools as much as I do, or is it just me?

hooah
Feb 6, 2006
WTF?

PiCroft posted:

Does anyone else struggle with Android tools? I've done both iOS and Android, and I coped well with both but by far the worst thing I've experienced in my career as a software developer is android tools. All the IDEs for android that I've tried, including Eclipse and Android Studio are a nightmare to get working with a mature project and getting a project with multiple modules working with Gradle was a headache. Does anyone else struggle with the tools as much as I do, or is it just me?

I'm just starting, but I already hate the LogCat viewer in Android Studio. The drat scroll lock button won't stay inactive, which is really frustrating when trying to look through a boatload of errors for the one specific line that's the actual error.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Probably still an improvement over the Eclipse one, which twitches constantly even though there's nothing new coming in

speng31b
May 8, 2010

PiCroft posted:

Does anyone else struggle with Android tools? I've done both iOS and Android, and I coped well with both but by far the worst thing I've experienced in my career as a software developer is android tools. All the IDEs for android that I've tried, including Eclipse and Android Studio are a nightmare to get working with a mature project and getting a project with multiple modules working with Gradle was a headache. Does anyone else struggle with the tools as much as I do, or is it just me?

Yeah, that goes without saying. For what it's worth, it's better than it used to be. I remember years ago when Eclipse was the only option aside from command line, and regularly restarting Eclipse was the norm - or even sometimes my whole PC when Eclipse ate it badly enough. It's not so bad when you have the luxury of developing your own workflow for a project, but when you inherit someone else's workflow, it's kind of a nightmare.

Just remember, it could always be worse. I have a coworker who reached the dex limit for an app through included libraries and had to go into the bowels of ProGuard for stripping third-party JARs just to get the count low enough to even compile the app.

zeekner
Jul 14, 2007

speng31b posted:

Just remember, it could always be worse. I have a coworker who reached the dex limit for an app through included libraries and had to go into the bowels of ProGuard for stripping third-party JARs just to get the count low enough to even compile the app.

I've had that happen as well. Avoid Guava if you can, it'll take 16k out of your 65k hard limit.

fritz
Jul 26, 2003

speng31b posted:

You have to call notifyDataSetChanged on the adapter whenever you change its underlying data unless you want to create a new adapter every time.

I thought I was, tho, in lines like
code:
        if (list.adapter != null) {
            list.adapter.notifyDataSetChanged();
        }
?

speng31b
May 8, 2010

I haven't pored over your logic extensively but that wouldn't get called in every case the adapter changes. You should call it right at the end of set_text because every time set_text gets called the data changes, not in MainActivity conditionally.

kitten smoothie
Dec 29, 2001

There's multi-dex support with the latest Android gradle tooling, though I don't know how reliable it is.

Also the new Play Services SDK now lets you individually select subsets of dependencies based on functionality, so you don't have to include a jar with 20K methods in it.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

PiCroft posted:

Does anyone else struggle with Android tools? I've done both iOS and Android, and I coped well with both but by far the worst thing I've experienced in my career as a software developer is android tools. All the IDEs for android that I've tried, including Eclipse and Android Studio are a nightmare to get working with a mature project and getting a project with multiple modules working with Gradle was a headache. Does anyone else struggle with the tools as much as I do, or is it just me?

I haven't done android in years. Glad to hear the tools are still poo poo.

I keep thinking about starting back into it and then I remember dealing with all the stuff outside of actually writing code and I just give up.

speng31b
May 8, 2010

Thermopyle posted:

I haven't done android in years. Glad to hear the tools are still poo poo.

I keep thinking about starting back into it and then I remember dealing with all the stuff outside of actually writing code and I just give up.

You make a career as an Android developer based on memorizing the best workflow to wade through a river of terrible idiosyncracies and overarchitected half-solutions. Also you come to the slow realization that everything you want to do with the Android libraries, Square already did better job of, so you just use one of their things instead. I'm not sure how Google hasn't absorbed Square yet.

speng31b fucked around with this message at 00:01 on Dec 19, 2014

hooah
Feb 6, 2006
WTF?
I've realized that my starter app doesn't show the icon in the main view (or the brand-new other view either). I found this post on the Udacity forums suggesting that the fix is setting the targetSdkVersion to 20 rather than 21. This does indeed make the icon show up, but that doesn't seem like the right way to go about it. Any wisdom to impart?

hooah fucked around with this message at 00:05 on Dec 19, 2014

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

I've realized that my starter app doesn't show the icon in the main view (or the brand-new other view either). I found this post on the Udacity forums suggesting that the fix is setting the targetSdkVersion to 20 rather than 21. This does indeed make the icon show up, but that doesn't seem like the right way to go about it. Any wisdom to impart?

Read the other answer in the link you posted.

hooah
Feb 6, 2006
WTF?

Volmarias posted:

Read the other answer in the link you posted.

Ah! That clears some up, but now Android Studio says it can't find those styles and colors, and I don't know enough about UI stuff yet to define them. But presumably by the time this course is over I will. I should also know more about reading poo poo for myself, I hope.

fritz
Jul 26, 2003

speng31b posted:

I haven't pored over your logic extensively but that wouldn't get called in every case the adapter changes. You should call it right at the end of set_text because every time set_text gets called the data changes, not in MainActivity conditionally.

Changing this
code:
        if (adapter != null) {
            adapter = new ArrayAdapter<String>(getActivity(),
                    android.R.layout.simple_list_item_1,
                    numbers_text);
            setListAdapter(adapter);
        }
to
code:

        if (adapter != null) {
            adapter.notifyDataSetChanged();
        }
in set_text still results in the old (incorrect) behavior.

hooah
Feb 6, 2006
WTF?
I'm having problems adding a new activity in AndroidManifest. Previously in this course, they've walked us through the steps of adding a new activity. I thought I'd done everything fine, and to the best of my ability have checked that the stuff I added for this new activity looks like the stuff for previous activities. However, in AndroidManifest.xml, Android Studio is complaining that the android:name".SettingsActivity" is not assignable to android.app.Activity. I've tried Googling for this error and reading the manifest documentation, but couldn't find anything that would explain why I might be getting this error.

fritz
Jul 26, 2003

More fragment woes. I'm trying to switch between multiple fragments on button press, but (a) I don't seem to be able to and (b) I get an exception saying the Fragment cannot create a View when I rotate.

Here's my MainActivity:
code:
package com.example.fbx;

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;


public class MainActivity extends ActionBarActivity {
    private final String TAG = "FBX";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void selectFragment(View view) {
        Fragment fragment;
        if (view == findViewById(R.id.button2)) {
            fragment = new FragmentTwo();
            Log.d(TAG, "Selected fragment two");

        } else if (view == findViewById(R.id.button1)) {
            fragment = new FragmentOne();
            Log.d(TAG, "Selected fragment one");
        } else {
            Log.e(TAG, "Invalid view!");
            return;
        }
        FragmentManager fm = getFragmentManager();
        FragmentTransaction fragmentTransaction = fm.beginTransaction();
        fragmentTransaction.replace(R.id.fragment_place, fragment);
        fragmentTransaction.commit();


    }

}
and my FragmentOne
code:
package com.example.fbx;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentOne extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_one, container, false);
    }
}

and FragmentTwo
code:
package com.example.fbx;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentTwo extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_two, container, false);
    }
}
XML files are:
code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <TextView android:text="@string/hello_world" android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ONE"
        android:id="@+id/button1"
        android:layout_below="@+id/textView"
        android:layout_alignParentStart="true"
        android:onClick="selectFragment"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TWO"
        android:id="@+id/button2"
        android:onClick="selectFragment"/>
    <fragment
        android:name="com.example.fbx.FragmentTwo"
        android:id="@+id/fragment_place"
        tools:layout="@layout/fragment_two"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>
for activity_main and
code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="FRAGMENT ONE"
        />
</LinearLayout>
for fragment_one and
code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="FRAGMENT TWO"
        />
</LinearLayout>
for fragment_two

I'm guessing this is more lifecycle issues where I'm not keeping things properly in order?

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

I'm having problems adding a new activity in AndroidManifest. Previously in this course, they've walked us through the steps of adding a new activity. I thought I'd done everything fine, and to the best of my ability have checked that the stuff I added for this new activity looks like the stuff for previous activities. However, in AndroidManifest.xml, Android Studio is complaining that the android:name".SettingsActivity" is not assignable to android.app.Activity. I've tried Googling for this error and reading the manifest documentation, but couldn't find anything that would explain why I might be getting this error.

Post the relevant snippet of manifest code, along with the package declaration line and class declaration line of your activity.

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer
What do you guys like to use for version control with your Android projects? I'm going to start working on my first-ever app soon and I want to have my versioning squared away ahead of time. I was thinking about using Github since everyone seems to include their githubs on their resumes these days (and all my day-job programming is proprietary so I can't show it off), but I have no idea how nicely it plays with Android Studio.

hooah
Feb 6, 2006
WTF?

Volmarias posted:

Post the relevant snippet of manifest code, along with the package declaration line and class declaration line of your activity.

Crap, I meant to include the manifest code.

AndroidManifest.xml
XML code:
<activity
    android:name=".SettingsActivity"
    android:label="@string/title_activity_settings"
    android:parentActivityName=".MainActivity" >
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="MainActivity" />
</activity>
Package declaration is package com.example.ben.sunshine;, class declaration is public class SettingsActivity extends PreferenceFragment implements Preference.OnPreferenceChangeListener.

Glimm
Jul 27, 2005

Time is only gonna pass you by

LeftistMuslimObama posted:

What do you guys like to use for version control with your Android projects? I'm going to start working on my first-ever app soon and I want to have my versioning squared away ahead of time. I was thinking about using Github since everyone seems to include their githubs on their resumes these days (and all my day-job programming is proprietary so I can't show it off), but I have no idea how nicely it plays with Android Studio.

I use Git, I'm sure there is an IntelliJ plugin for it but I'm not sure how good it is (I just use the command line).

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

Crap, I meant to include the manifest code.

AndroidManifest.xml
XML code:
<activity
    android:name=".SettingsActivity"
    android:label="@string/title_activity_settings"
    android:parentActivityName=".MainActivity" >
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="MainActivity" />
</activity>
Package declaration is package com.example.ben.sunshine;, class declaration is public class SettingsActivity extends PreferenceFragment implements Preference.OnPreferenceChangeListener.

PreferenceFragment is not a subclass of Activity.

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer

Glimm posted:

I use Git, I'm sure there is an IntelliJ plugin for it but I'm not sure how good it is (I just use the command line).

Sweet, I'll just go with Git then. We use SVN at work, but Github's client looks pretty usable.

hooah
Feb 6, 2006
WTF?

Volmarias posted:

PreferenceFragment is not a subclass of Activity.

Ok. I don't understand what that implies. They told us if we wanted to target Honeycomb+ to use PreferenceFragment rather than PreferenceActivity.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

Ok. I don't understand what that implies. They told us if we wanted to target Honeycomb+ to use PreferenceFragment rather than PreferenceActivity.

It means that you placed a not-activity peg into an activity hole. Create an activity to hold the fragment and point to that in your manifest.

Also, OO fundamentals :negative:

hooah
Feb 6, 2006
WTF?

Volmarias posted:

It means that you placed a not-activity peg into an activity hole. Create an activity to hold the fragment and point to that in your manifest.

Ok, I'm on my way to doing that, but the code generated by the IDE when I (re)created the SettingsActivity class complains that it can't resolve add(int, com.example.hooah.sunshine.SettingsActivity.SettingsFragment) in onCreate, and likewise for menu_settings in onCreateOptionsMenu. I definitely have a menu_settings.xml, but I have no idea what this R business is all about.

Java code:
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new SettingsFragment())
                    .commit();
        }
    }
Java code:
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_settings, menu);
        return true;
    }

quote:

Also, OO fundamentals :negative:

In what regard? I consider myself at least moderately competent in OO in C++, but I don't see what enormous thing I'm missing here.

Edit: Looking at the compiler error (rather than the editor error), it seems it can't match the add signature because it can't convert SettingsFragment to Fragment. My SettingsFragment doesn't derive directly from Fragment, but what it's extending (PreferenceFragment) does. Is this extra level of subclassing the reason the add function's signature isn't satisfied?

hooah fucked around with this message at 00:19 on Dec 20, 2014

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
You're using the support library, which provides fragments to older devices which do not run Android 3.0 or above. Fragments were added in 3.0. You use the supportFragmentManager for classes that extend android.support.v4.app.Fragment, which SettingsFragment does not. There's no native support version, but others have made their own. Alternately, use SettingsActivity.

If you want to limit yourself to 3.0 and up (you probably do honestly) don't use support fragments, instead just use fragments and call getFragmentManager.

hooah
Feb 6, 2006
WTF?

Volmarias posted:

Alternately, use SettingsActivity.

This was what I ended up doing. I missed SettingsActivity as a built-in thing to add, likely because I was hung up on the wording in the video. Now the IDE isn't yelling at me anymore, but the settings item in the overflow menu doesn't seem to do anything. However, I can't remember right now if it's supposed to yet, so that'll be another problem for another day. Thanks.

hooah fucked around with this message at 03:53 on Dec 20, 2014

hooah
Feb 6, 2006
WTF?
I've got another problem I can't figure out. The course showed us how to add one type of preference to set the location via a postal code. Now we're to create a setting to choose which type of units. I know I need to use a ListPreference, but I'm having trouble getting the XML to cooperate. I found a tutorial that recommended creating an arrays.xml file and defining the arrays for android:entries and android:entryValues[fixed]. I did that fine, but in the pref_general.xml file where I try to use those arrays like [fixed]android:entries="@arrays/pref_temperature_type", I get an error "Unknown resource type arrays". I'm likely mistaken, but it seems to me that Android Studio doesn't know where arrays.xml is, even though it's in app/src/main/res/values. If that's the problem, how do I fix it? If not, then what is the problem?

ButtaKnife
Mar 12, 2007

"I WILL DEVOUR 100 GENERATIONS OF YOUR FAMILY!"

PiCroft posted:

Does anyone else struggle with Android tools? I've done both iOS and Android, and I coped well with both but by far the worst thing I've experienced in my career as a software developer is android tools. All the IDEs for android that I've tried, including Eclipse and Android Studio are a nightmare to get working with a mature project and getting a project with multiple modules working with Gradle was a headache. Does anyone else struggle with the tools as much as I do, or is it just me?

The tools are definitely not fully polished, but my goodness is Android Studio leaps and bounds better than Eclipse/ADT. It seems like Google is finally putting some effort into making better tooling. We have a large, mature project at work with three different build configurations creating different package names, using some similar and different libraries, and swapping in different .java files. ...and each with debug and release versions. In Ant, this was a spaghetti-nightmare. In Gradle, it was extremely straightforward except for a couple of little things that we wanted to modify/exclude, and even those weren't too bad with a couple of extra lines of code in build.gradle.

kitten smoothie posted:

There's multi-dex support with the latest Android gradle tooling, though I don't know how reliable it is.

Also the new Play Services SDK now lets you individually select subsets of dependencies based on functionality, so you don't have to include a jar with 20K methods in it.

The Multidex support library is actually really nice from what I've seen. Guava, Play Services, and all of the heavy-hitters are no problem. I'm using it in a side project right now and it's working well.

Glimm posted:

I use Git, I'm sure there is an IntelliJ plugin for it but I'm not sure how good it is (I just use the command line).

First, I highly recommend using Git in some fashion. GitHub is great for projects that you just want to do for fun and to show off your coding. Second, the Git plugin for IntelliJ is decent, though I actually miss some behaviors from EGit. Still, it works well enough and there's always the command line if you need it.

Volmarias posted:

You're using the support library, which provides fragments to older devices which do not run Android 3.0 or above. Fragments were added in 3.0. You use the supportFragmentManager for classes that extend android.support.v4.app.Fragment, which SettingsFragment does not. There's no native support version, but others have made their own. Alternately, use SettingsActivity.

If you want to limit yourself to 3.0 and up (you probably do honestly) don't use support fragments, instead just use fragments and call getFragmentManager.

At this point, I'd disagree with your last assertion. I think even targeting 14+ it's a good idea to use support fragments. At least with the support libraries, if there are bugs, they can be fixed in the library. If there are bugs in the OS, well, gently caress.

Also, the AppCompat v21+ library includes Material Design components for non-Lollipop devices, but you'll need to be using the support classes to take full advantage of it. So just do that.

Glimm
Jul 27, 2005

Time is only gonna pass you by

ButtaKnife posted:

At this point, I'd disagree with your last assertion. I think even targeting 14+ it's a good idea to use support fragments. At least with the support libraries, if there are bugs, they can be fixed in the library. If there are bugs in the OS, well, gently caress.

Also, the AppCompat v21+ library includes Material Design components for non-Lollipop devices, but you'll need to be using the support classes to take full advantage of it. So just do that.

As annoying as the support lib can be I've got to agree, even targeting 4.x+ I'd recommend using it.

speng31b
May 8, 2010

ButtaKnife posted:

At this point, I'd disagree with your last assertion. I think even targeting 14+ it's a good idea to use support fragments. At least with the support libraries, if there are bugs, they can be fixed in the library. If there are bugs in the OS, well, gently caress.

Also, the AppCompat v21+ library includes Material Design components for non-Lollipop devices, but you'll need to be using the support classes to take full advantage of it. So just do that.

I deal with crash logs for an app with 1mil+ users that uses support library Fragments for 14+ support only, and more of our crashes come from unpatched, known support Fragment issues than any other source by far. It's nice in theory, but in practice, the support library Fragments have all the bugs that the individual OS versions do, but they don't get resolved on newer OS versions - they perpetuate, so the Fragment manager bugs introduced in 14, and fixed in 15, you get to deal with for every version because the bug is in the support lib that's never been patched so OS upgrades don't help at all.

But yeah, you have to use them anyhow if you support 14+ and think you ever might need nested Fragments (for a ViewPager full of Fragments inside a Fragment, most commonly), since you don't get a child Fragment manager without support libs unless you target 17+, and noone can realistically afford to target only 17+. You just lose too much market share.

In other words, yeah, I guess you don't have much choice. But support Fragments are a loving nightmare and definitely not more stable than built-ins.

speng31b fucked around with this message at 00:15 on Dec 21, 2014

ButtaKnife
Mar 12, 2007

"I WILL DEVOUR 100 GENERATIONS OF YOUR FAMILY!"

speng31b posted:

I deal with crash logs for an app with 1mil+ users that uses support library Fragments for 14+ support only, and more of our crashes come from unpatched, known support Fragment issues than any other source by far. It's nice in theory, but in practice, the support library Fragments have all the bugs that the individual OS versions do, but they don't get resolved on newer OS versions - they perpetuate, so the Fragment manager bugs introduced in 14, and fixed in 15, you get to deal with for every version because the bug is in the support lib that's never been patched so OS upgrades don't help at all.

But yeah, you have to use them anyhow if you support 14+ and think you ever might need nested Fragments (for a ViewPager full of Fragments inside a Fragment, most commonly), since you don't get a child Fragment manager without support libs unless you target 17+, and noone can realistically afford to target only 17+. You just lose too much market share.

In other words, yeah, I guess you don't have much choice. But support Fragments are a loving nightmare and definitely not more stable than built-ins.

Oh absolutely, the bugs actually need to be fixed so it's more theory than practice right now. Our app (with millions of users across a wide variety of devices and countries) actually gets more crashes from the Android internal graphics library than fragments, but it is an issue.

The other nice thing about going full support library: nearly free future-proofing. Anyone already using appcompat before v21 got a nice visual refresh for little to no work besides a new build/publish. We weren't (and still aren't in the Prod build but will be changing) so our app still barely looks Holo.

Adbot
ADBOT LOVES YOU

speng31b
May 8, 2010

Yeah, it was nice to be able to push out a build with a few material gimmicks basically overnight with just a few XML theme tweaks.

My favorite part about toolbar replacing actionbar is that it's an actual view in your hierarchy that you have direct control over rather than a separate window layer hovering over everything untouchable through all but the weirdest reflection hacks.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply