Reputation: 311
I've created an activity in android that has a Swipe layout. It uses Fragments for the different tabs when swiped. Now I want to place a different spinner in each of those Tabs/Fragments. The data for the spinner is loaded from a mysql server. The data loads and is placed in the spinner. But now i don't know how to place that spinner in one fragment. It works when I place the spinner in a blank activity but I don't know where to place it in the fragment code.
package com.example.vanhulzenapp;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Locale;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
public class DisplayProductList extends FragmentActivity implements
ActionBar.TabListener {
TextView text_1,text_2 ;
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_product_list);
new task().execute();
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Show the Up button in the action bar.
actionBar.setDisplayHomeAsUpEnabled(true);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
class task extends AsyncTask<String,Integer,Void>
{
private ProgressDialog progressDialog = new ProgressDialog(DisplayProductList.this);
InputStream is = null ;
String result = "";
protected void onPreExecute() {
progressDialog.setMessage("Download data...");
progressDialog.show();
progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface arg0) {
task.this.cancel(true);
}
});
}
@Override
protected Void doInBackground(String... params) {
String url_select = "http://192.168.2.2/select.php";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_select);
ArrayList param = new ArrayList();
try {
httpPost.setEntity(new UrlEncodedFormEntity(param));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
//read content
is = httpEntity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection "+e.toString());
}
try {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = "";
while((line=br.readLine())!=null)
{
sb.append(line+"\n");
}
is.close();
result=sb.toString();
} catch (Exception e) {
// TODO: handle exception
Log.e("log_tag", "Error converting result "
+e.toString());
}
return null;
}
protected void onPostExecute(Void v) {
// ambil data dari Json database
try {
JSONArray Jarray = new JSONArray(result);
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>
(DisplayProductList.this, android.R.layout.simple_spinner_item );
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
for(int i=0;i<Jarray.length();i++)
{
Log.i("log_tag", "Jarray length - " + Jarray.length());
Log.i("log_tag", "Jarray Object - " + Jarray.getJSONObject(i));
JSONObject Jasonobject = null;
text_1 = (TextView)findViewById(R.id.txt1);
Jasonobject = Jarray.getJSONObject(i);
adapter.add(Jasonobject.getString("ProductName"));
Log.i("log_tag", "adapter Item - " + adapter.getItem(i));
}
Spinner s = (Spinner) findViewById(R.id.ddName);
s.setAdapter(adapter);
this.progressDialog.dismiss();
} catch (Exception e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.display_product_list, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
**/
public static final String ARG_SECTION_NUMBER = "section_number";
public DummySectionFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_display_product_list_dummy, container,
false);
/*
TextView dummyTextView = (TextView) rootView
.findViewById(R.id.section_label);
dummyTextView.setText(Integer.toString(getArguments().getInt(
ARG_SECTION_NUMBER))); */
return rootView;
}
}
}
I think this is the part where it should happen:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_display_product_list_dummy, container,
false);
/*
TextView dummyTextView = (TextView) rootView
.findViewById(R.id.section_label);
dummyTextView.setText(Integer.toString(getArguments().getInt(
ARG_SECTION_NUMBER))); */
return rootView;
}
But I'm not sure how to connect that with the result that happens in the onPostExecute where the data is placed in the spinner.
Spinner s = (Spinner) findViewById(R.id.ddName);
s.setAdapter(adapter);
I really hope someone can help me cause I really get stuck on this.
Tnx a lot in advance
Upvotes: 1
Views: 2058
Reputation: 900
You are right about needing to create the spinners in each of your fragment's onCreateView() methods. So, you would need to make sure to have the three spinners defined in your three layout files for your fragments.
Now, about getting the data from the AsyncTask.. what I would probably end up doing is calling the async task within each of the three fragments. That way you can write each task specific to what the fragment needs. Doing it that way would allow you to easily add the data to the spinner.
So, you would first make your spinner accessible to the entire class:
Spinner mSpinner;
Then, in onCreateView():
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_display_product_list_dummy, container,
false);
mSpinner = (Spinner) rootView.findViewById(R.id.frag1spinner);
}
And then finally, in the onPostExecute() for the fragment, assign the adapter:
mSpinner.setAdapter(adapter);
That's more or less how I would do it. Anyone please let me know the good or bad with this ;)
Upvotes: 2
Reputation: 62549
to me i think you should keep a reference to the spinner or the adapter as a top level member and then in the fragments onCreateView you can set the adapter and populate it. After the data changes in onPostExecute can you not call notifyDataSetChanged on your adapter ?
Upvotes: 0