2017-12-26 12 views
0

Ich habe eine App erstellt, die eine Liste von 10 Büchern basierend auf einem Abfrage-Schlüsselwort anzeigt, das vom Benutzer eingegeben wurde.Steuern eines AsynTaskLoaders mit einem Klick auf die Schaltfläche

Ich habe eine EditText Ansicht für den Benutzer verwendet, um die Abfrage einzugeben.

Ich habe auch eine ImageButton für die Suchschaltfläche verwendet.

Ich habe eine benutzerdefinierte Klasse verwendet, die AsyncTaskLoader erweitert, um Inhalt zu meinem ListView zu laden.

Ich habe die initloader() Methode aus der MainActivity der App aufgerufen und hat meinen benutzerdefinierten Lader aus der OnCreateLoader Override-Methode aufgerufen.

Ich möchte, dass der Loader die Daten nur auf Knopfdruck und nicht automatisch beim Start der Aktivität abruft.

Hauptaktivität

package com.example.shara.booklistapp; 

import android.app.LoaderManager; 
import android.content.Context; 
import android.content.Intent; 
import android.content.Loader; 
import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.net.Uri; 
import android.provider.ContactsContract; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ImageView; 
import android.widget.ListView; 
import android.widget.ProgressBar; 
import android.widget.TextView; 

import java.util.ArrayList; 
import java.util.List; 

import static android.app.LoaderManager.*; 
import static com.example.shara.booklistapp.BookQueryUtils.LOG_TAG; 

public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Blist>> { 
    private ListAdapter mAdapter; 
    private static final int BOOK_LOADER_ID = 1; 
    private String Book_list_request_url = "Michael Jackson"; 
    private ProgressBar progressBar; 
    private NetworkInfo networkInfo; 
    private TextView emptytextview; 
    private EditText editText; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     ListView booklistview = findViewById(R.id.list); 
     progressBar = findViewById(R.id.progressbar); 
     mAdapter = new ListAdapter(this, new ArrayList<Blist>()); 
     booklistview.setAdapter(mAdapter); 
     ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
     networkInfo = connectivityManager.getActiveNetworkInfo(); 
     emptytextview = (TextView) findViewById(R.id.emptytextview); 
     editText = findViewById(R.id.search_query_text_view); 
     booklistview.setEmptyView(emptytextview); 
     booklistview.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       Blist currentBook = mAdapter.getItem(position); 
       Uri currentbookk = Uri.parse(currentBook.getUrl()); 

       startActivity(new Intent(Intent.ACTION_VIEW, currentbookk)); 
      } 
     }); 

     LoaderManager loaderManager = getLoaderManager(); 
     loaderManager.initLoader(BOOK_LOADER_ID, null, this); 
    } 

    //Overriding the abstract methods of the Loadermanager 
    @Override 
    public Loader<List<Blist>> onCreateLoader(int id, Bundle bundle) { 
     Log.i(LOG_TAG, Book_list_request_url); 
     return new BlistLoader(this, Book_list_request_url); 
    } 

    @Override 
    public void onLoadFinished(Loader<List<Blist>> loader, List<Blist> blists) { 

     progressBar.setVisibility(View.GONE); 

     //Using the networkInfo variable declared earlier to check whether the system has internet connectivity and displays a message if there isn't one. 
     if (networkInfo == null) { 
      emptytextview.setText(R.string.no_network); 
     } else { 
      emptytextview.setVisibility(View.GONE); 
     } 

     mAdapter.clear(); 
     if (blists != null && !blists.isEmpty()) { 
      mAdapter.addAll(blists); 

     } 
    } 

    @Override 
    public void onLoaderReset(Loader loader) { 
     Log.i(LOG_TAG, "Testing: onLoaderReset is successfully called"); 
     mAdapter.clear(); 
    } 
} 

Benutzerdefinierte Loader-Klasse

package com.example.shara.booklistapp; 

import android.content.AsyncTaskLoader; 
import android.content.Context; 
import android.util.Log; 
import android.widget.BaseAdapter; 
import android.widget.Button; 
import android.widget.ImageButton; 

import org.json.JSONException; 

import java.io.IOException; 
import java.util.List; 

public class BlistLoader extends AsyncTaskLoader<List<Blist>> { 
    private static final String LOG_TAG = BaseAdapter.class.getName(); 
    private String mUrl; 

    public BlistLoader(Context context, String url) { 
     super(context); 

     mUrl = url; 
    } 

    @Override 
    protected void onStartLoading() { 
     Log.i(LOG_TAG, "Testing: onStartLoading is successfully called"); 
     forceLoad(); 
    } 

    @Override 
    public List<Blist> loadInBackground() { 

     Log.i(LOG_TAG, "Testing: loadInBackground is successfully called"); 
     if (mUrl == null) { 
      return null; 
     } 
     List<Blist> blists = null; 
     try { 
      blists = BookQueryUtils.fetchBookList(mUrl); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     return blists; 
    } 
} 

XML, das das Image enthält

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 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" 
    android:orientation="vertical" 
    tools:context=".MainActivity"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_margin="10dp" 
     android:orientation="horizontal"> 

     <EditText 
      android:id="@+id/search_query_text_view" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_weight="2" 
      android:hint="@string/hint" /> 

     <ImageButton 
      android:id="@+id/search_button1" 
      android:layout_width="42dp" 
      android:layout_height="42dp" 
      android:src="@drawable/search" /> 

    </LinearLayout> 

    <TextView 
     android:id="@+id/result" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="10dp" 
     android:backgroundTint="@color/colorPrimaryDark" 
     android:backgroundTintMode="add" 
     android:text="Results" /> 

    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <ListView 
      android:id="@+id/list" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_margin="10dp" 
      android:dividerHeight="1dp" /> 

     <ProgressBar 
      android:id="@+id/progressbar" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerInParent="true" /> 

     <TextView 
      android:id="@+id/emptytextview" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerInParent="true" 
      android:text="" /> 
    </RelativeLayout> 

</LinearLayout> 

Ich mag die oncreateloader Methode nur ausgeführt werden, wenn die Suchtaste angeklickt wird und nicht anders.

Wie kann dies erreicht werden? Muss mein Code stark modifiziert werden oder ist es etwas, das ich komplett vermisst habe?

Ich habe vorher die gleiche Frage gestellt here, aber ich habe keine Antworten erhalten. Jede Hilfe würde sehr geschätzt werden.

Buch Abfrage utils ist für die HTTP-Anfrage und JSON Parsing.

package com.example.shara.booklistapp; 

import android.net.Uri; 
import android.text.TextUtils; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.nio.charset.Charset; 
import java.util.ArrayList; 
import java.util.List; 

/** 
* Created by shara on 12/17/2017. 
*/ 

public final class BookQueryUtils { 

    public static final String LOG_TAG = BookQueryUtils.class.getName(); 

    private BookQueryUtils() { 

    } 

    private static URL createURL(String search_query) throws MalformedURLException { 
     URL url = null; 
     String q = "q"; 
     try { 
      final String base_URL = "https://www.googleapis.com/books/v1/volumes?"; 
      Uri final_Url = Uri.parse(base_URL).buildUpon() 
        .appendQueryParameter(q, search_query) 
        .build(); 
      url = new URL(final_Url.toString()); 
      Log.i(LOG_TAG, "The final Url is" + url); 
     } catch (MalformedURLException e) { 
      Log.e(LOG_TAG, "Url could not be formed", e); 
     } 
     return url; 
    } 

    private static String theHTTPRequest(URL url) throws IOException { 
     String jsonResponse = ""; 
     if (url == null) { 
      return jsonResponse; 
     } 
     HttpURLConnection connectionUrl = null; 
     InputStream theInputStream = null; 

     try { 
      connectionUrl = (HttpURLConnection) url.openConnection(); 
      connectionUrl.setReadTimeout(10000); 
      connectionUrl.setConnectTimeout(15000); 
      connectionUrl.setRequestMethod("GET"); 
      connectionUrl.connect(); 
      if (connectionUrl.getResponseCode() == 200) { 
       theInputStream = connectionUrl.getInputStream(); 
       jsonResponse = readFromStream(theInputStream); 
      } else { 
       Log.e(LOG_TAG, "could not make the connection"); 
      } 
     } catch (IOException e) { 
      Log.e(LOG_TAG, "Problem getting the requested data", e); 
     } finally { 
      if (connectionUrl != null) { 
       connectionUrl.disconnect(); 
      } 
      if (theInputStream != null) { 
       theInputStream.close(); 
      } 
     } 
     return jsonResponse; 
    } 

    private static String readFromStream(InputStream inputStream) throws IOException { 
     StringBuilder streamoutput = new StringBuilder(); 
     InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8")); 
     BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 
     String urlline = bufferedReader.readLine(); 
     while (urlline != null) { 
      streamoutput.append(urlline); 
      urlline = bufferedReader.readLine(); 
     } 
     return streamoutput.toString(); 
    } 

    private static List<Blist> extractFeatureFromJSON(String BlistJSON) throws JSONException { 
     if (TextUtils.isEmpty(BlistJSON)) { 
      return null; 
     } 

     List<Blist> blists = new ArrayList<>(); 
     try { 
      String a = ""; 
      JSONObject baseJSON = new JSONObject(BlistJSON); 
      JSONArray items = baseJSON.getJSONArray("items"); 
      for (int i = 0; i < items.length(); i++) { 
       Blist blistss = new Blist(); 
       JSONObject j = items.getJSONObject(i); 
       JSONObject vInfo = j.getJSONObject("volumeInfo"); 
       if (vInfo.has("authors")) { 
        JSONArray athrs = vInfo.getJSONArray("authors"); 
        if (athrs.length() != 0) { 
         for (int k = 0; k < athrs.length(); k++) { 
          a = athrs.getString(k); 
          blistss.setAuthor(a); 
         } 
        } 
       } 
       if (vInfo.has("imageLinks")) { 
        JSONObject thumbnail = vInfo.getJSONObject("imageLinks"); 
        blistss.setImage(thumbnail.getString("thumbnail")); 
       } 
       blistss.setUrl(vInfo.getString("previewLink")); 
       blistss.setTitle(vInfo.getString("title")); 
       blistss.setPublisher(vInfo.getString("publisher")); 
       blists.add(blistss); 
      } 
     } catch (JSONException e) { 
      Log.e(LOG_TAG, "Could not parse JSON", e); 
     } 
     return blists; 
    } 

    public static List<Blist> fetchBookList(String query_url) throws IOException, JSONException { 
     URL url = createURL(query_url); 
     String JSONResponse = null; 
     try { 
      JSONResponse = theHTTPRequest(url); 
     } catch (IOException e) { 
      Log.e(LOG_TAG, "Could not fetch data"); 
     } 
     List<Blist> blists = extractFeatureFromJSON(JSONResponse); 
     return blists; 
    } 
} 

Dies ist mein Adapter für die Listview.

package com.example.shara.booklistapp; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.os.AsyncTask; 
import android.provider.ContactsContract; 
import android.support.annotation.NonNull; 
import android.support.annotation.Nullable; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ImageView; 
import android.widget.ProgressBar; 
import android.widget.SearchView; 
import android.widget.TextView; 

import java.io.InputStream; 
import java.util.ArrayList; 

/** 
* Created by shara on 12/17/2017. 
*/ 

public class ListAdapter extends ArrayAdapter<Blist> { 
    private ProgressBar progressBar; 

    public ListAdapter(@NonNull Context context, ArrayList<Blist> blists) { 
     super(context, 0, blists); 
    } 

    public String rslt; 

    @NonNull 
    @Override 
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { 
     View listitemview = convertView; 
     if (listitemview == null) { 
      listitemview = LayoutInflater.from(getContext()).inflate(R.layout.list_layout, parent, false); 
     } 
     Blist blist = getItem(position); 

     ImageView thumbnail = listitemview.findViewById(R.id.thumbnail_imageview); 
     new imageLoader(thumbnail).execute(blist.getImage()); 
     progressBar = listitemview.findViewById(R.id.Image_Progress_bar); 
     progressBar.setVisibility(View.GONE); 
     TextView title = listitemview.findViewById(R.id.title_textview); 
     title.setText(blist.gettitle()); 

     TextView author = listitemview.findViewById(R.id.author_textview); 
     author.setText(blist.getauthor()); 
     TextView publisher = listitemview.findViewById(R.id.publisher_texview); 
     publisher.setText(blist.getpublisher()); 

     return listitemview; 
    } 

    private class imageLoader extends AsyncTask<String, Void, Bitmap> { 
     ImageView bmImage; 

     public imageLoader(ImageView bmImage) { 
      this.bmImage = bmImage; 
     } 

     protected Bitmap doInBackground(String... urls) { 
      String urldisplay = urls[0]; 
      Bitmap mIcon11 = null; 
      try { 
       InputStream in = new java.net.URL(urldisplay).openStream(); 
       mIcon11 = BitmapFactory.decodeStream(in); 
      } catch (Exception e) { 
       Log.e("Error", e.getMessage()); 
       e.printStackTrace(); 
      } 
      return mIcon11; 
     } 

     protected void onPostExecute(Bitmap result) { 

      bmImage.setImageBitmap(result); 

     } 
    } 
} 
+0

Anruf initiateloader Methode OnClick von Image. 'loaderManager.initLoader (BOOK_LOADER_ID, null, das);' zur imagebutton Klickmethode. –

+0

@MohamedMohaideenAH Das hat es, Sir. Vielen Dank für Ihre Zeit und Hilfe. Ich rief initloader an und ordnete die Suchabfrage der Variablen Booklistqueryurl innerhalb des onclick des Bildknopfes zu. –

+0

Es funktioniert gut beim ersten Klick auf den Suchknopf, aber es macht nichts bei nachfolgenden Klicks. Wie kann ich die Liste basierend auf verschiedenen Keywords aktualisieren, ohne die App neu zu starten? –

Antwort

0

in-Code

Sie anfangs leere Abfrage

private String Book_list_request_url = ""; 

Methode für "Search Klicken Sie auf (Imagebutton)" Aktualisiert

public void Search(View v) 
{ 
    Book_list_request_url = editText.getText().toString(); 
    loaderManager.restartLoader(BOOK_LOADER_ID, null, this); 
} 

Add-Methode

zu Image
<ImageButton 
     android:id="@+id/search_button1" 
     android:layout_width="42dp" 
     android:layout_height="match_parent" 
     android:onClick="Search" 
     android:src="@drawable/ic_launcher_background" /> 

enter image description here

+0

Vielen Dank Herr. Ich habe etwas ähnliches versucht, konnte es aber nicht richtig funktionieren. –

+0

Willkommen froh zu helfen.! –

+0

Akzeptieren Sie die Antwort, wenn die Frage gelöst wurde. Es hilft anderen, die gleichen Probleme zu lösen. –

Verwandte Themen