2017-11-23 1 views
1

내 코드의 버튼 중 하나에 대해 setOnClickListener 메소드에 문제가 있습니다. 기본적으로 발생하는 것은 setOnClickListener 메서드 내에서 typeFinder를 호출하지만 버튼을 처음 누르면 값이 업데이트되지 않습니다. 나는 디버거를 사용했는데 어떤 일이 일어 났는지는 함수가 호출 되더라도 setOnClickListener가 끝날 때까지 프로그램이 실제로 함수를 거치지 않는다는 것을 의미한다. 즉 두 번째로 버튼을 누를 때 표시 할 값이 올바르다는 것을 의미한다. 이전 버튼 누름에서. TypesTask를 사용해 보았는데 (페이지 하단의 주석 부분에서 볼 수 있듯이), 그렇게하면 같은 결과가 발생합니다. 여기 는 클래스의 코드입니다 : 여기 버튼 setOnClickListener와 관련된 문제

import android.os.AsyncTask; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 
import com.google.firebase.database.DataSnapshot; 
import com.google.firebase.database.DatabaseError; 
import com.google.firebase.database.DatabaseReference; 
import com.google.firebase.database.FirebaseDatabase; 
import com.google.firebase.database.ValueEventListener; 

import java.util.ArrayList; 

public class MainActivity extends AppCompatActivity { 
    private static final String TAG = "MainActivity"; 
    private DatabaseReference myRef; 
    private ArrayList<String> recipesList = new ArrayList<String>(); 
    private String[] types = {"pizza", "ice cream", "sandwich", "salad", "steak"}; 
    private void typeFinder(String type) { 
     myRef.orderByChild("type").equalTo(type).addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       // This method is called once with the initial value and again 
       // whenever data at this location is updated. 
       String word = ""; 
       boolean wordAdded = false; 
       String value = dataSnapshot.getValue().toString(); 
       for (int i = 0; i < value.length(); i++) { 
        if (wordAdded == false) { 
         if (value.charAt(i) == '=') { 
          recipesList.add(word); 
          wordAdded = true; 
          word = ""; 
         } else if (value.charAt(i) != '{' && value.charAt(i) != ',') { 
          if (word.length() == 0 && value.charAt(i) == ' ') { 
          } else { 
           word = word + value.charAt(i); 
          } 
         } 
        } 
        if (value.charAt(i) == '}') 
         if (i + 2 == value.length()) { 
          wordAdded = false; 
          break; 
         } else 
          wordAdded = false; 
       } 
      } 
      @Override 
      public void onCancelled(DatabaseError error) { 
       // Failed to read value 
       Log.w(TAG, "Failed to read value.", error.toException()); 
      } 
     }); 
    } 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     setContentView(R.layout.activity_main); 
     myRef = FirebaseDatabase.getInstance().getReference(); 
     Button saladsB = (Button) findViewById(R.id.saladButton); 
     Button pizzaB = (Button) findViewById(R.id.pizzaButton); 
     Button iceCreamB = (Button) findViewById(R.id.iceCreamButton); 
     Button steakB = (Button) findViewById(R.id.steakButton); 
     Button sandwichB = (Button) findViewById(R.id.sandwichButton); 
     final TextView testTextView = (TextView) findViewById(R.id.test_text_view); 
     testTextView.setText(Integer.toString(recipesList.size())); 
     super.onCreate(savedInstanceState); 
     saladsB.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       // recipesList.clear(); 
      // t.typeFinder("salad") 
        typeFinder("salad"); 
      //  new TypesTask().execute("salad"); 
       String recipes = ""; 
       for (int i = 0; i < recipesList.size(); i++) { 
        recipes = recipes + recipesList.get(i) + "\n"; 
       } 
       testTextView.setText(recipes); 
       // Intent intent = new Intent(MainActivity.this, ListviewActivity.class); 
       // intent.putStringArrayListExtra("FOOD_LIST", recipesList); 
       // startActivity(intent); 
      } 
     }); 
    } 
    /* 
    public class TypesTask extends AsyncTask<String, Void, Void> { 
     @Override 
     protected void onPreExecute() { 
      myRef = FirebaseDatabase.getInstance().getReference(); 
     } 
     @Override 
     protected Void doInBackground(String... params) { 
      typeFinder(params[0]); 
      return null; 
     } 
    } 
    */ 
} 

<?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" 
    tools:context="com.example.thevash.recipes.MainActivity"> 

    <LinearLayout 
     android:layout_width="0dp" 
     android:layout_height="810dp" 
     android:layout_marginEnd="8dp" 
     android:layout_marginStart="8dp" 
     android:layout_marginTop="458dp" 
     android:orientation="horizontal" 
     app:layout_constraintHorizontal_bias="1.0" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintRight_toRightOf="parent" 
     app:layout_constraintTop_toTopOf="parent" 
     tools:layout_constraintLeft_creator="1" 
     tools:layout_constraintRight_creator="1" 
     tools:layout_constraintTop_creator="1"> 


     <TextView 
      android:id="@+id/test_text_view" 
      android:layout_width="585dp" 
      android:layout_height="248dp" 
      android:layout_weight="1" 
      android:text="TextView" 
      tools:layout_editor_absoluteX="8dp" 
      tools:layout_editor_absoluteY="-377dp" /> 
    </LinearLayout> 

    <Button 
     android:id="@+id/saladButton" 
     android:layout_width="0dp" 
     android:layout_height="48dp" 
     android:text="Salads" 
     tools:layout_constraintTop_creator="1" 
     tools:layout_constraintRight_creator="1" 
     app:layout_constraintRight_toRightOf="parent" 
     android:layout_marginTop="5dp" 
     tools:layout_constraintLeft_creator="1" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintTop_toTopOf="parent" /> 

    <Button 
     android:id="@+id/pizzaButton" 
     android:layout_width="0dp" 
     android:layout_height="48dp" 
     android:text="Pizzas" 
     tools:layout_constraintTop_creator="1" 
     tools:layout_constraintRight_creator="1" 
     app:layout_constraintRight_toRightOf="parent" 
     android:layout_marginTop="52dp" 
     tools:layout_constraintLeft_creator="1" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintTop_toTopOf="parent" /> 

    <Button 
     android:id="@+id/iceCreamButton" 
     android:layout_width="0dp" 
     android:layout_height="48dp" 
     android:text="ice cream" 
     tools:layout_constraintTop_creator="1" 
     tools:layout_constraintRight_creator="1" 
     app:layout_constraintRight_toRightOf="@+id/pizzaButton" 
     app:layout_constraintTop_toBottomOf="@+id/pizzaButton" 
     tools:layout_constraintLeft_creator="1" 
     app:layout_constraintLeft_toLeftOf="@+id/pizzaButton" /> 

    <Button 
     android:id="@+id/steakButton" 
     android:layout_width="0dp" 
     android:layout_height="48dp" 
     android:text="steaks" 
     tools:layout_constraintTop_creator="1" 
     tools:layout_constraintRight_creator="1" 
     app:layout_constraintRight_toRightOf="@+id/iceCreamButton" 
     app:layout_constraintTop_toBottomOf="@+id/iceCreamButton" 
     tools:layout_constraintLeft_creator="1" 
     app:layout_constraintLeft_toLeftOf="@+id/iceCreamButton" /> 

    <Button 
     android:id="@+id/sandwichButton" 
     android:layout_width="0dp" 
     android:layout_height="48dp" 
     android:text="sandwiches" 
     tools:layout_constraintTop_creator="1" 
     tools:layout_constraintRight_creator="1" 
     app:layout_constraintRight_toRightOf="@+id/steakButton" 
     app:layout_constraintTop_toBottomOf="@+id/steakButton" 
     tools:layout_constraintLeft_creator="1" 
     app:layout_constraintLeft_toLeftOf="@+id/steakButton" /> 
</android.support.constraint.ConstraintLayout> 
+0

이것을 [mcve]로 줄일 수 있습니까? –

+0

값을 추출하기 위해 데이터베이스에 연결하고 있기 때문에 가능한지 확실하지 않습니다. – siashim

+0

'myRef.orderByChild ("type"). equalTo (type) .addValueEventListener'로 이동하여 onCreate를 초기화하여 작동 여부를 확인하십시오. – kimkevin

답변

1

당신이 사용 TypesTask을 할 수있는 페이지의 XML입니다하지만 당신은 같은 TypesTask 클래스를 수정해야 아래

public class TypesTask extends AsyncTask<String, Void, Void> { 
    @Override 
    protected void onPreExecute() { 
     myRef = FirebaseDatabase.getInstance().getReference(); 
    } 
    @Override 
    protected Void doInBackground(String... params) { 
     typeFinder(params[0]); 
     return null; 
    } 
    @Override 
    onPostExecute(Void result){ 
     String recipes = ""; 
     for (int i = 0; i < recipesList.size(); i++) { 
       recipes = recipes + recipesList.get(i) + "\n"; 
     } 
     testTextView.setText(recipes); 
    } 
} 

이고 onClick은 이와 같아야합니다.

saladsB.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      new TypesTask().execute("salad"); 

     } 
    }); 
+0

고맙습니다. 이것은 거의 트릭을했습니다. 방금 변수를 업데이트 할 충분한 시간을주기 위해 typeFinder를 호출 한 후 잠시 동안 프로그램을 잠자 게해야했습니다. 그 후 완벽하게 작동했습니다. testTextView.setText (recipes)는 onCreate() 내에서만 액세스 할 수 있으므로 testTextView.setText (recipes)는 호출 할 수 없지만 출력을 다른 방식으로 테스트 했으므로 완벽하게 작동했습니다. – siashim

0

reciepeList를 작성하는 방법은 비동기 호출입니다. EventListener의 OnSuccess() 호출 후 Ui의 변경 사항을 업데이트해야합니다.

private void typeFinder(String type) { 
    myRef.orderByChild("type").equalTo(type).addValueEventListener(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      // This method is called once with the initial value and again 
      // whenever data at this location is updated. 
      String word = ""; 
      boolean wordAdded = false; 
      String value = dataSnapshot.getValue().toString(); 
      for (int i = 0; i < value.length(); i++) { 
       if (wordAdded == false) { 
        if (value.charAt(i) == '=') { 
         recipesList.add(word); 
         wordAdded = true; 
         word = ""; 
        } else if (value.charAt(i) != '{' && value.charAt(i) != ',') { 
         if (word.length() == 0 && value.charAt(i) == ' ') { 
         } else { 
          word = word + value.charAt(i); 
         } 
        } 
       } 
       if (value.charAt(i) == '}') 
        if (i + 2 == value.length()) { 
         wordAdded = false; 
         break; 
        } else 
         wordAdded = false; 
      } 

     // Update the Ui Here 
      String recipes = ""; 
      for (int i = 0; i < recipesList.size(); i++) { 
       recipes = recipes + recipesList.get(i) + "\n"; 
      } 
      this.testTextView.setText(recipes); 
     } 
     @Override 
     public void onCancelled(DatabaseError error) { 
      // Failed to read value 
      Log.w(TAG, "Failed to read value.", error.toException()); 
     } 
    }); 
} 
+0

정말 고마워요. 이 방법도 효과가있었습니다. 이 일을 위해 수면을 추가 할 필요가 없었습니다. 다른 대답과 마찬가지로 onTextView.setText (recipes)는 onCreate() 내에서만 액세스 할 수 있기 때문에 거기에서 호출 할 수 없다는 점에 유의해야합니다. 그러나 그것은 내 검사 동안 효과가있었습니다. – siashim

0

코멘트에 일을 제공하는 답변을 모두 언급 한 바와 같이 : 아래의 코드를 참조 OnDataChange에 UI 그 갱신 코드를 변경합니다. UI 업데이트를 typeFinder 함수 자체에 추가하거나 AsyncTask를 사용하여 onPostExecute 메서드 내부의 UI를 업데이트해야했습니다. 후자의 경우 변수를 업데이트 할 충분한 시간을주기 위해 typeFinder (params [0]) 행 다음에 프로그램을 잠자기 상태로 두어야했습니다.