2016-10-20 6 views
0

안녕하세요 저는 서버에 연결하고 게시물 목록을 얻는 안드로이드의 간단한 응용 프로그램을 만들었습니다. 그러면 각 게시물의 제목으로 채워지는 spinner이 있고 선택할 수 있습니다 그들 중 하나.Spinner가 선택한 항목을 표시하지 않습니다

게시물을 선택해야하는 시점까지는 모두 작동합니다. spinner을 열면 하나만 선택하면 아무 것도 나타나지 않고 게시물이 spinner에서 선택되지 않고 텍스트가 변경되지 않습니다. 나는 스피너는 항목을 표시되지하지만 그것이 작동하지 수 10 게시물처럼 읽을, 저를 도와주세요, 이건 내 자바 코드 :

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

'onCreate'에'spinner.setOnItemSelectedListener'를 넣으면 더 좋을 것이라고 생각합니다. 데이터를 가져 오기위한 백그라운드 프로세스를 집중해야합니다. – 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);을 사용하여 비동기 호출이 완료되었는지 여부를 선택합니다. 이 예외를 throw해야하는지 여부를 잊었습니다. 당신은 즉시 당신의 회 전자의 요소를 업데이트하려면

    @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 스레드에 있지 않으므로 오류가 발생합니다.

    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(); 
        } 
    } 
    
    : 당신은 당신이 당신의 자신의 사용자 정의 어댑터가 가정 데이터

를 가져 오는에 AsyncTask을 집중해야한다고 말했다 이유입니다, 여기에 데이터의 갱신을 처리 할 수있는 내 사용자 지정 어댑터입니다

물론 이것은 단지 예일뿐입니다.

요약 다음과 같이

시도가 코드를 업데이트 :이 도움이

//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); 
    } 
} 

희망!

관련 문제