0

私はアンドロイドが初めてで、いくつか問題があります。2 つのスピナーを作成しました。最初のものは YEARS を取得して取得し、最初のスピナーを動的に設定します。ユーザーが選択した年に基づいて、2 番目のスピナーが作動し、その特定の年の自動車メーカー (フォード、ホンダなど) を取得して、2 番目のスピナーを動的に更新します。アプリを起動すると、最初のスピナーに年が正しく入力されますが、年を選択すると選択が選択されません。私は周りを読んでいて、すべてのコードが正しいと 90% 確信していますが、一部は間違った場所にあると思います。たとえば、onCreate メソッドをもっと使用する必要がありますか? 各スピナーを異なる方法で分割する必要がありますか? 誰かが私が間違っていることを教えてもらえますか、それともあなたがとても親切なら、それが機能するように再フォーマットしてください? これが私のコードです。

public class MainActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

    final Spinner year=(Spinner)findViewById(R.id.spinner_year);
    final Spinner make=(Spinner)findViewById(R.id.spinner_make);

    final ArrayList<String> year_options = new ArrayList<String>();
    final ArrayList<String> make_options = new ArrayList<String>();


    /*
     * ASYNC TASK CLASSES
     */

    class populateYear extends AsyncTask<URL, Void, NodeList> {
        protected NodeList doInBackground(URL... urls) {
            NodeList yearList = null;
            try {
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                DocumentBuilder db = dbf.newDocumentBuilder();
                Document doc = db.parse(urls[0].openStream());
                Element docEle = doc.getDocumentElement();

                yearList = docEle.getElementsByTagName("menuItem");


            } catch (Exception e) {
                System.out.println(e);
            }
            return yearList;

        }

        protected void onPostExecute(NodeList yearList) {

            if (yearList != null && yearList.getLength() > 0) {
                for (int i = 0; i < yearList.getLength(); i++) {
                    Node node = yearList.item(i);
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        Element e = (Element) node;
                        NodeList nodeList = e.getElementsByTagName("text");
                        year_options.add(nodeList.item(0).getChildNodes().item(0).getNodeValue());
                    }
                }
            } else {
                System.exit(1);
            }

        }
    }


    class populateMake extends AsyncTask<String, Void, NodeList> {
        protected NodeList doInBackground(String... strings) {
            NodeList makeList = null;
            try {
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                DocumentBuilder db = dbf.newDocumentBuilder();
                //Building a URL with "strings[0]" being equal to the year that we pass to the class.
                URL url = new URL("http://www.fueleconomy.gov/ws/rest/vehicle/menu/make?year=" + strings[0]);
                Document doc = db.parse(url.openStream());
                Element docEle = doc.getDocumentElement();

                makeList = docEle.getElementsByTagName("menuItem");


            } catch (Exception e) {
                System.out.println(e);
            }
            return makeList;

        }

        protected void onPostExecute(NodeList makeList) {

            if (makeList != null && makeList.getLength() > 0) {
                for (int i = 0; i < makeList.getLength(); i++) {
                    Node node = makeList.item(i);
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        Element e = (Element) node;
                        NodeList nodeList = e.getElementsByTagName("text");
                        make_options.add(nodeList.item(0).getChildNodes().item(0).getNodeValue());
                    }
                }
            } else {
                System.exit(1);
            }

        }
    }


    /*
     * END OF ASYNC TASK CLASSES
     */


    final ArrayAdapter<String> yearAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item,year_options);

    //Filling the YEAR SPINNER
    URL xmlURL = null;
    try {
        xmlURL = new URL("http://www.fueleconomy.gov/ws/rest/vehicle/menu/year");
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //Parse the XML and use the value by calling the AsyncTaskClass
    new populateYear().execute(xmlURL);

    //Setting the Year Adapter
    year.setAdapter(yearAdapter);

    final ArrayAdapter<String> makeAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item,make_options);
    //Disabling the MAKE spinner onLoad. Will be enabled later when user picks a year.
    make.setEnabled(false);
    //Setting the Make Adapter
    make.setAdapter(makeAdapter);  



    //Adding the listener for when someone selects a YEAR
    year.setOnItemSelectedListener(new OnItemSelectedListener() {


        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

            year.setSelection(position);
            String selectedYear=year_options.get(position).toString();




            resetMake(selectedYear);                               
        }
        @Override
        public void onNothingSelected(AdapterView<?> arg0) {

        }

        public void resetMake(String selectedYear) {      
            //Clear the ArrayList belonging to MAKE so you can add new data based on the YEAR selection
            make_options.clear();
            new populateMake().execute(selectedYear);

            //Clear the makeAdapter and then add the new makes bases on the YEAR selection.
            makeAdapter.clear();
            for(int i=0; i < make_options.size(); i++) {
                makeAdapter.add(make_options.get(i));
            }
            makeAdapter.notifyDataSetChanged();
            make.setEnabled(true);
        }


}
4

1 に答える 1

1

のポイントは、アプリが実行を継続できるようにAsyncTask、スレッドから非同期に実行することです。UIこれは、タスクを開始すると、関数内の残りのコードが引き続き実行されることを意味します。このため、実行を入力public void resetMake(String selectedYear) {するAsyncTaskと、その関数の残りのコードもAdapter入力されます。つまり、新しいデータがダウンロードされる前に入力しようとします。

これを処理するには、いくつかの方法があります。タスクをそのタスクに実行した後、その関数内のすべてのコードを移動するだけですonPostExecute()

protected void onPostExecute(NodeList makeList) {

        if (makeList != null && makeList.getLength() > 0) {
            for (int i = 0; i < makeList.getLength(); i++) {
                Node node = makeList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element e = (Element) node;
                    NodeList nodeList = e.getElementsByTagName("text");
                    make_options.add(nodeList.item(0).getChildNodes().item(0).getNodeValue());
                }
            }
  //Clear the makeAdapter and then add the new makes bases on the YEAR selection.
        makeAdapter.clear();
        for(int i=0; i < make_options.size(); i++) {
            makeAdapter.add(make_options.get(i));
        }
        makeAdapter.notifyDataSetChanged();
        make.setEnabled(true);
        } else {
            System.exit(1);
        }

    }

これを行うと、関数はそのままになります

 public void resetMake(String selectedYear) {      
        //Clear the ArrayList belonging to MAKE so you can add new data based on the YEAR selection
        make_options.clear();
        new populateMake().execute(selectedYear);

したがって、それをonItemSelected()最初の に移動しSpinnerて、この機能を廃止することができます。

このコードが完全であることを確認していないことに注意してください。構文エラーがあり、コンパイルできるように中括弧などを移動する必要がある場合があります。

その他の注意事項

Views通常はinを初期化しますがonCreate()、メンバー変数として宣言することもでき、通常は in にする必要はありませんfinal。これにより、コードが読みやすくなります。したがって、クラスの冒頭は次のようになります。

  public class MainActivity extends Activity {
    Spinner year, make; // you can declare them here so you can use them anywhere in the Activity

    ArrayList<String> year_options = new ArrayList<String>();
    ArrayList<String> make_options = new ArrayList<String>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        year = (Spinner)findViewById(R.id.spinner_year);  // and initialize them here
        make=(Spinner)findViewById(R.id.spinner_make);
    }
于 2013-07-03T00:55:59.887 に答える