PagerSlidingTabStrip- custom view using list fragm

2019-09-06 11:52发布

问题:

I am using PagerSlidingTabStrip to create a sliding tabs. I was successfully able to use this library in my project.

Based on selected/clicked tab, the application should send a get request to server to fetch data and populate the list view. Every-time the tab is selected, http call would be made to server and list view will be updated.

I just modify SuperAwesomeCardFragment.java in the sample:

public class SuperAwesomeCardFragment extends ListFragment {

private ListView listView;
private ArrayList<User> arrayOfUsers = new ArrayList<User>();
private UsersAdapter useradapter;
ProgressDialog mProgressDialog;
ArrayList<HashMap<String, String>> arraylist;
JSONObject jsonobject;
JSONArray ja;

private static final String ARG_POSITION = "position";
private int position;

public static SuperAwesomeCardFragment newInstance(int position) {
    SuperAwesomeCardFragment f = new SuperAwesomeCardFragment();
    Bundle b = new Bundle();
    b.putInt(ARG_POSITION, position);
    f.setArguments(b);
    return f;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    position = getArguments().getInt(ARG_POSITION);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    new DownloadJSON().execute();
    View rootView = inflater.inflate(R.layout.fragment,
            container, false);
    listView = (ListView) rootView.findViewById(android.R.id.list);
    useradapter = new UsersAdapter(getActivity(), android.R.id.list, arrayOfUsers);
    listView.setAdapter(useradapter);
    //Return the View for the fragment's UI
    return rootView;
}

// DownloadJSON AsyncTask
private class DownloadJSON extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Create a progressdialog
        mProgressDialog = new ProgressDialog(getActivity());
        // Set progressdialog title
        mProgressDialog.setTitle("Connecting to server");
        // Set progressdialog message
        mProgressDialog.setMessage("Serving...");
        mProgressDialog.setIndeterminate(false);
        // Show progressdialog
        mProgressDialog.show();
    }

    @Override
    protected Void doInBackground(Void... params) {
        String statusStr;
        switch (position) {
            case 0:
                statusStr = "UNREAD";
                break;
            case 1:
                statusStr = "PROCCC";
                break;
            case 2:
                statusStr = "COMPLETE";
                break;
            default:
                statusStr = "UNKNOWN";
        }
        arraylist = new ArrayList<HashMap<String, String>>();
        jsonobject = JSONfunctions
                .getJSONfromURL("http://example.com/?id=" + statusStr);
        try {
            // Locate the array name in JSON
            ja = jsonobject.getJSONArray("all_orders");
        } catch (JSONException e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void args) {
        arrayOfUsers.clear();
        arrayOfUsers.addAll(User.fromJson(ja));
        System.out.println(arrayOfUsers.toString());
        listView.setAdapter(useradapter);
        // Close the progressbar
        mProgressDialog.dismiss();
        useradapter.notifyDataSetChanged();
    }
}

} Didn't touch any other file.

Here is the custom adapter(UserAdapter.java) which I have created:

public class UsersAdapter extends ArrayAdapter<User> {
private  Context context;
private List<User> objects;
public UsersAdapter(Context context, int textViewResourceId, List<User> objects) {
    super(context, textViewResourceId, objects);
    // TODO Auto-generated constructor stub
    this.objects=objects;
    this.context = context;
}

private  class ViewHolder {
    TextView name;
    TextView home;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder; // view lookup cache stored in tag
    // Get the data item for this position
    User user = getItem(position);
    // Check if an existing view is being reused, otherwise inflate the view
    LayoutInflater mInflater = (LayoutInflater) context
            .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {
        viewHolder = new ViewHolder();
        convertView = mInflater.inflate(R.layout.list_row, null);
        viewHolder.name = (TextView) convertView.findViewById(R.id.tvName);
        viewHolder.home = (TextView) convertView.findViewById(R.id.tvHome);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    // Populate the data into the template view using tYiuhe data object
    viewHolder.name.setText(user.ord_name);
    viewHolder.home.setText(user.ord_id);
    // Return the completed view to render on screen
    return convertView;
}

I was able to run the application successfully(Didn't see any error or exceptions in Log Cat). However, the behaviour is quite abrupt:

  1. Load App For the first time: When I press Tab 1 and Tab 2, then its fetches the data and populate the list-view(Expected). However, it do not refresh/fetch data from server when I press last tab(Tab 3).
  2. Once I finished clicking all three tabs: Tab 1 and Tab 3 do not fetch data, neither load list. The fragment is blank. Only Tab 2 shows list view, but do not refresh data from server. The total number of tab equals 3.

Behaviour 2 is repeated every time, whatever combination I try.

I am quite new to Android development, so not able debug this behaviour.

Any help is appreciated.

UPD: I was able to bring desired behaviour by over-riding setUserVisibleHint:

public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (isVisibleToUser) {
            new DownloadJSON().execute();
            Log.d("MyFragment", "Fragment is visible.");
        }
        else {

            Log.d("MyFragment", "Fragment is not visible.");
        }
    }

Is this the prescribed way?

回答1:

I looked a bit your code but I found some errors:

first change this :

    @Override
    protected void onPostExecute(Void args) {
    arrayOfUsers.clear();
    arrayOfUsers.addAll(User.fromJson(ja));
    if(useradapter!=null){
    useradapter.notifyDataSetChanged();
    }
        // Close the progressbar
    mProgressDialog.dismiss();
    }

next: Create your Users Array like this:

private ArrayList<User> arrayOfUsers=new ArrayLit<User>();

change this:

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment,
            container, false);
    listView = (ListView) rootView.findViewById(android.R.id.list);
    if(userAdapter==null){
    userAdapter=new UsersAdapter(getActivity(), android.R.id.list,arrayOfUsers);
    listView.setAdapter(userAdapter);
    }
    return rootView;
}