2016-10-20 15 views
0

こんにちは私は、サーバーに接続して投稿のリストを取得するアンドロイドで単純なアプリを作った、そしてspinnerは各投稿のタイトルで満たされ、それらの中の一つ。Spinnerは選択された項目を表示しません

私は投稿を選択する必要がある時点まですべて動作します。spinnerを開きます。選択したすべてのタイトルが表示され、何も起こらず、投稿はspinnerで選択されず、テキストは変更されません、私はスピナーの項目を示していないが、私はそれを動作させることができなかった約10件の記事のように読んで、私を助けてください、これは私のJavaコードです:

package com.example.lagarto.blog; 

import android.graphics.Color; 
import android.os.AsyncTask; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.ArrayAdapter; 
import android.widget.TextView; 

import org.w3c.dom.Text; 

import java.sql.Connection; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement; 
import java.util.ArrayList; 
import android.util.Log; 
import android.widget.Spinner; 

public class MainActivity extends AppCompatActivity { 
    ArrayList<Post> archivo=new ArrayList<Post>(); 
    ArrayList<String> titulos=new ArrayList<String>(); 
    public ArrayAdapter<String> spinnerArrayAdapter; 
    private static final String TAG= MainActivity.class.getSimpleName(); 
    private class GetDBConnection extends AsyncTask<Integer, Void, String>{ 
     @Override 
     protected String doInBackground(Integer... params) { 
      try{ 
       Connection conn= DBConnection.getInstance().getConnection(); 
       Statement st= conn.createStatement(); 
       String sql=("SELECT * FROM posts"); 
       ResultSet rs=st.executeQuery(sql); 
       while(rs.next()) { 
        int id = rs.getInt("Id"); 
        String title = rs.getString("Title"); 
        String body = rs.getString("Body"); 
        String date = rs.getString("Date"); 
        Post post = new Post(id, title, body, date); 
        archivo.add(post); 
        System.out.println(archivo); 
       } 
       Log.d(TAG,"Terminado"); 
      }catch(SQLException e){ 
       e.printStackTrace(); 
      } 
      return "Valido"; 
     } 

     @Override 
     protected void onPostExecute(String result) { 
      Spinner spinner=(Spinner) findViewById(R.id.spinner); 
      spinner.setVisibility(View.VISIBLE); 
      for (Post i:archivo) { 
       titulos.add(i.getTitle()); 
      } 
      TextView title=(TextView) findViewById(R.id.title); 
      TextView body=(TextView) findViewById(R.id.body); 
      title.setVisibility(View.VISIBLE); 
      body.setVisibility(View.VISIBLE); 
      TextView connection=(TextView) findViewById(R.id.connection); 
      connection.setVisibility(View.INVISIBLE); 
      spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
       @Override 
       public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
        spinnerArrayAdapter.notifyDataSetChanged(); 
        Post resultado=archivo.get(position); 
        title.setText(resultado.getTitle()); 
        body.setText(resultado.getBody()); 
       } 

       @Override 
       public void onNothingSelected(AdapterView<?> parent) { 
        spinnerArrayAdapter.notifyDataSetChanged(); 
        Post resultado=archivo.get(0); 
        title.setText(resultado.getTitle()); 
        body.setText(resultado.getBody()); 
       } 
      }); 

     } 
    } 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     new GetDBConnection().execute(0); 
     Spinner spinner=(Spinner) findViewById(R.id.spinner); 
     spinnerArrayAdapter=new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, titulos); 
     spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     spinner.setAdapter(spinnerArrayAdapter); 
     spinner.setSelection(1); 
     System.out.println(archivo); 



    } 


} 

そして、これは私のXMLコードです:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_main" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.example.lagarto.blog.MainActivity"> 



    <TextView 
     android:layout_width="400dp" 
     android:layout_height="50dp" 
     android:text="Hello World!" 
     android:textSize="30dp" 
     android:textAlignment="center" 
     android:layout_alignParentEnd="true" 
     android:id="@+id/title" 
     android:layout_marginTop="40dp" 
     android:visibility="invisible" 
     /> 
    <TextView 
     android:layout_width="400dp" 
     android:layout_height="500dp" 
     android:text="Hello World!" 
     android:textSize="16dp" 
     android:layout_marginTop="100dp" 
     android:layout_alignParentEnd="true" 
     android:id="@+id/body" 
     android:visibility="invisible" 
     /> 

    <Spinner 
     android:layout_width="400dp" 
     android:layout_height="50dp" 
     android:layout_alignParentTop="true" 
     android:layout_centerHorizontal="true" 
     android:id="@+id/spinner" 
     android:textSize="20dp" 
     android:visibility="invisible" 
     android:backgroundTint="@color/colorPrimaryDark" 
     android:textAlignment="center" 
     /> 

    <TextView 
     android:text="Waiting for connection please wait" 
     android:layout_width="400dp" 
     android:layout_height="100dp" 
     android:textSize="30dp" 
     android:textAlignment="center" 
     android:layout_marginTop="150dp" 
     android:id="@+id/connection" /> 


</RelativeLayout> 
+1

'spinner.setOnItemSelectedListener'を' onCreate'に置いたほうが良いでしょう。 データを取得するためのバックグラウンド処理に専念する必要があります。 – cipley

+0

それはバグを修正しません:/ –

+0

奇数... 'onPostExecute'が完了した後にlogcatを取得していますか? – cipley

答えて

0

ここに私の評価があります:

TL; DR

あなたがバックグラウンドスレッドでUIを更新しようとしました。

説明:あなたのスピナーがある前に、あなたがGetDBConnectionと呼ば

  • これはonCreate

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        new GetDBConnection().execute(0); 
        Spinner spinner=(Spinner) findViewById(R.id.spinner); 
        spinnerArrayAdapter=new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, titulos); 
        spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
        spinner.setAdapter(spinnerArrayAdapter); 
        spinner.setSelection(1); 
        System.out.println(archivo); 
    } 
    

    にこれに基づいていくつかのポインタコードのあなたの作品です準備ができている。 GetDBConnectionはバックグラウンドで非同期に実行されるため、の設定をonItemSelectedListener(後で説明します)に設定すると、スピンナを設定する競合条件が作成されます。

  • あなたのスピナーには人が住んでいるようですが、にもかかわらず良い練習ではありませんでした。
  • 次に、spinner.setSelection(1);を使用して非同期呼び出しが完了したかどうかを選択します。これが例外を投げるべきかどうか忘れてしまった。あなたがその場であなたのスピナーの要素を更新する場合

    @Override   
    protected void onPostExecute(String result) { 
        Spinner spinner=(Spinner) findViewById(R.id.spinner); 
        spinner.setVisibility(View.VISIBLE); 
        for (Post i:archivo) { 
         titulos.add(i.getTitle()); 
        } 
        TextView title=(TextView) findViewById(R.id.title); 
        TextView body=(TextView) findViewById(R.id.body); 
        title.setVisibility(View.VISIBLE); 
        body.setVisibility(View.VISIBLE); 
        TextView connection=(TextView) findViewById(R.id.connection); 
        connection.setVisibility(View.INVISIBLE); 
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
         @Override 
         public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
          spinnerArrayAdapter.notifyDataSetChanged(); 
          Post resultado=archivo.get(position); 
          title.setText(resultado.getTitle()); 
          body.setText(resultado.getBody()); 
         } 
         @Override 
         public void onNothingSelected(AdapterView<?> parent) { 
          spinnerArrayAdapter.notifyDataSetChanged(); 
          Post resultado=archivo.get(0); 
          title.setText(resultado.getTitle()); 
          body.setText(resultado.getBody()); 
         } 
        }); 
    } 
    
    • が、あなたはまた、(更新、追加、削除する方法を含めるべきか、アップデート:今すぐ上のコードのごonPostExecute作品へ

    )あなたのアダプタのList要素。

  • 前述のように、リスナーをAsyncTaskに入れることは、おそらく適用可能ですが、良い方法ではありません。あなたもUIを変更しようと言うことは言うまでもありません(TextViewの値を設定する)。呼び出しがUIスレッドにないため、エラーが発生します。私はあなたがデータをフェッチにAsyncTaskを集中すべきだと述べた理由ですのみ

ここで、あなたがあなた自身のカスタム・アダプタを持っていると仮定すると、データの更新を処理することができ、私のカスタムアダプタです:

public abstract class CustomListAdapter<T> extends BaseAdapter { 
    protected List<T> mData = new ArrayList<>(); 
    protected LayoutInflater mInflater; 
    protected ViewHolder holder; 

    /*truncated*/ 

    public void addItem(T item){ 
     mData.add(item); 
     notifyDataSetChanged(); 
    } 

    public void clear(){ 
     mData = new ArrayList<>(); 
     notifyDataSetChanged(); 
    } 

    public void deleteItem(int position){ 
     mData.remove(position); 
     notifyDataSetChanged(); 
    } 

    public void fill(Collection<T> items){ 
     mData.addAll(items); 
     notifyDataSetChanged(); 
    } 
} 

もちろん、これは単なる例です。

概要

は、次のようにコードを更新するようにしてください:

//Declare your elements here first; 

TextView title; 
TextView body; 
TextView connection; 
Spinner spinner; 

private class GetDBConnection extends AsyncTask<Integer, Void, String>{ 
    @Override 
    protected String doInBackground(Integer... params) { 
     try{ 
      Connection conn= DBConnection.getInstance().getConnection(); 
      Statement st= conn.createStatement(); 
      String sql=("SELECT * FROM posts"); 
      ResultSet rs=st.executeQuery(sql); 
      while(rs.next()) { 
       int id = rs.getInt("Id"); 
       String title = rs.getString("Title"); 
       String body = rs.getString("Body"); 
       String date = rs.getString("Date"); 
       Post post = new Post(id, title, body, date); 
       archivo.add(post); 
       System.out.println(archivo); 
      } 
      Log.d(TAG,"Terminado"); 
     }catch(SQLException e){ 
      e.printStackTrace(); 
     } 
     return "Valido"; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     /* 
      all code that changes your UI should resides in the UI Thread. This is still in Background Thread. 
     */ 
     //Spinner spinner=(Spinner) findViewById(R.id.spinner); --> this is also unneccessary 
     //spinner.setVisibility(View.VISIBLE); 

     /* 
      something like this is possible as long as it doesn't change your UI. 
     */ 
     for (Post i:archivo) { 
      titulos.add(i.getTitle()); 
      /* 
      - update your Adapter List elements here. 
      */ 
     } 
     // - also call your adapter notifyDataSetChanged here, if neccessary. 

     //TextView title=(TextView) findViewById(R.id.title); --> unneccessary! 
     //TextView body=(TextView) findViewById(R.id.body); --> unneccessary! 
     //title.setVisibility(View.VISIBLE); 
     //body.setVisibility(View.VISIBLE); 
     //TextView connection=(TextView) findViewById(R.id.connection); --> unneccessary! 
     //connection.setVisibility(View.INVISIBLE); 

     /* 
      instead, you can call another method that resides in the UI Thread 
     */ 
     // updateUI(); 
     /* 
      or, execute them under runOnUIThread() 
     */ 
     runOnUIThread(new Runnable(){ 
      @Override 
      public void run(){ 
       spinner.setVisibility(View.VISIBLE); 
       title.setVisibility(View.VISIBLE); 
       body.setVisibility(View.VISIBLE); 
       connection.setVisibility(View.INVISIBLE); 
      } 
     }); 
    } 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     /* 
      you should initiate ALL your UI elements on the onCreate() 
     */ 
     spinner=(Spinner) findViewById(R.id.spinner); 
     title=(TextView) findViewById(R.id.title); 
     body=(TextView) findViewById(R.id.body); 
     connection=(TextView) findViewById(R.id.connection); 
     spinnerArrayAdapter=new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, titulos); 
     spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     /* 
      then, set your listeners 
     */ 
     spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
      @Override 
      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
       //spinnerArrayAdapter.notifyDataSetChanged(); --> this is unneccessary 
       Post resultado=archivo.get(position); 
       title.setText(resultado.getTitle()); 
       body.setText(resultado.getBody()); 
      } 
      @Override 
      public void onNothingSelected(AdapterView<?> parent) { 
       //spinnerArrayAdapter.notifyDataSetChanged(); --> this is unneccessary 
       Post resultado=archivo.get(0); 
       title.setText(resultado.getTitle()); 
       body.setText(resultado.getBody()); 
      } 
     }); 
     spinner.setAdapter(spinnerArrayAdapter); 
     System.out.println(archivo); 

     new GetDBConnection().execute(0); // --> After all has been set, then execute your AsyncTask. 
    } 

    private void updateUI(){ 
     spinner.setVisibility(View.VISIBLE); 
     title.setVisibility(View.VISIBLE); 
     body.setVisibility(View.VISIBLE); 
     connection.setVisibility(View.INVISIBLE); 
    } 
} 

・ホープ、このことができます!

関連する問題