简体   繁体   中英

CustomListView not populated in Android's Fragment

In the fragment(called VideoCallFragment) is launched, the first action is to request data to the server (Ruby) and gather data and populate to the listview. In order to see whether it's done, I make a progressdialog and onPostExcute, I use responseView.textSet(response). However the data was not populated after loading is done.

However if I make a EditText view in the same layout ( empty one ), and if I click that one ( although I didn't make this EditText view as an being able to process after that ), then the data was populated. But it is obvious that users will not like this unnecessary process. Is this caused by delay between AsnyTask and rootView initilization in VideoCallFragment? I put my code for this situation.

And being also suspicious about the adapter(listview), I

final ListView lv=(ListView) rootView.findViewById(R.id.listView_classroom);
CustomAdapter adapter = new CustomAdapter(getActivity(), prgmNameList, dateList, caseList);
lv.setAdapter(adapter);
adapter.notifyDatasetChanged();

where prgmNameList, dateList, caseList are all ArrayList that I make as a variable in VideoCallFrament Class.

However the final line didn't work and says "Cannot resolve method notifyDatasetChanged(); So I'm lost here :(

CustomAdapter looks like this.

public class CustomAdapter extends BaseAdapter{

    ArrayList classroom_name_result;
    ArrayList date_result;
    ArrayList case_result;
    String [] tutor_result;

    Context context;
    int [] imageId;
    private static LayoutInflater inflater=null;

    public CustomAdapter(Activity mainActivity, ArrayList prgmNameList, ArrayList datelist, ArrayList caselist /*, int[] prgmImages*/) {
        // TODO Auto-generated constructor stub

        classroom_name_result= prgmNameList;
        date_result = datelist;
        case_result = caselist;
        context=mainActivity;
        inflater = ( LayoutInflater )context.
                getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return classroom_name_result.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    public class Holder
    {
        TextView tv;
        TextView date;
        TextView mcase;
        ImageView img;

    }
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        Holder holder=new Holder();
        View rowView;
        rowView = inflater.inflate(R.layout.program_list, null);

        holder.tv=(TextView) rowView.findViewById(R.id.lesson);
        holder.tv.setText(classroom_name_result.get(position).toString());

        holder.date=(TextView) rowView.findViewById(R.id.date);
        holder.date.setText(date_result.get(position).toString());

        holder.mcase=(TextView) rowView.findViewById(R.id.course);
        holder.mcase.setText(case_result.get(position).toString());
        return rowView;
    }

}

The first below is MainActivity that has fragments. And the fragment called VideoCallFragment is the class that doesn't populate correctly.

public class MainActivity extends ActionBarActivity
        implements NavigationDrawerFragment.NavigationDrawerCallbacks {

    some variables...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mainactivity2);

        mNavigationDrawerFragment = (NavigationDrawerFragment)
                getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
        mTitle = getTitle();
        mNavigationDrawerFragment.setUp(
                R.id.navigation_drawer,
                (DrawerLayout) findViewById(R.id.drawer_layout));
    }

    @Override
    public void onNavigationDrawerItemSelected(int position) {
        // update the main content by replacing fragments
        FragmentManager fragmentManager = getSupportFragmentManager();
        Fragment fragmentToLaunch = getFragmentToLaunch(position);
        fragmentManager.beginTransaction()
                .replace(R.id.container, fragmentToLaunch)
                .commit();
    }

    public void onSectionAttached(int number) {
        switch (number) {
            case CASE_SECTION_EDIT_PROFILE:
                mTitle = getString(R.string.title_section1);
                break;
            case CASE_SECTION_VIDEO_CALL:
                mTitle = getString(R.string.title_section2);
                break;
            default:
                break;
        }
    }

    public void restoreActionBar() {
        ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setTitle(mTitle);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (!mNavigationDrawerFragment.isDrawerOpen()) {
            // Only show items in the action bar relevant to this screen
            // if the drawer is not showing. Otherwise, let the drawer
            // decide what to show in the action bar.
            getMenuInflater().inflate(R.menu.main, menu);
            restoreActionBar();
            return true;
        }
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_build_info) {
            String versionInfo = "SDK Version: " + sg.com.temasys.skylink.sdk.BuildConfig.VERSION_NAME
                    + "\n" + "Sample application version: " + BuildConfig.VERSION_NAME;
            Log.d(TAG, versionInfo);
            Toast.makeText(this, versionInfo, Toast.LENGTH_LONG).show();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    public Fragment getFragmentToLaunch(int position) {
        Fragment fragmentToLaunch = null;
        switch (position) {
            case CASE_FRAGMENT_EDIT_PROFILE:
                fragmentToLaunch = new EditProfileFragment();
                break;
            case CASE_FRAGMENT_VIDEO_CALL:
                fragmentToLaunch = new VideoCallFragment();
                break;

            default:
                break;
        }

        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, position + 1);
        fragmentToLaunch.setArguments(args);

        return fragmentToLaunch;
    }
}

VideoCallFragment

public class VideoCallFragment extends Fragment implements LifeCycleListener, MediaListener, RemotePeerListener {
    some varaibles.....

    private ArrayList<String> prgmNameList = new ArrayList<String>();
    private ArrayList<String> caseList = new ArrayList<String>();
    private ArrayList<String> dateList = new ArrayList<String>();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_video_call, container, false);
        parentFragment = (LinearLayout) rootView.findViewById(R.id.ll_video_call);

        etRoomName = (EditText) rootView.findViewById(R.id.et_room_name);
        etRoomName.setVisibility(View.GONE);

        responseView = (TextView) rootView.findViewById(R.id.responseView);

        SharedPreferences settings = PreferenceManager
                .getDefaultSharedPreferences(getContext());
        String auth_token_string = settings.getString("token", ""/*default value*/);

        final ListView lv=(ListView) rootView.findViewById(R.id.listView_classroom);

        CustomAdapter adapter = new CustomAdapter(getActivity(), prgmNameList, dateList, caseList);
        lv.setAdapter(adapter);


        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                String classroom = ((TextView) view.findViewById(R.id.lesson)).getText().toString();
                Toast.makeText(getActivity(), classroom, Toast.LENGTH_SHORT).show();
                lv.setVisibility(View.GONE);
                classroom_enter(classroom);
            }
        });
        new soonClass().execute(auth_token_string);
        return rootView;
    }


    class soonClass extends AsyncTask<String, String, String> {
        ProgressDialog pd;
        private Exception exception;
        protected void onPreExecute() {

            pd = new ProgressDialog(getActivity());
            pd.setMessage("Logining..");
            pd.show();

        }

        protected String doInBackground(String... args) {


            String auth_token_string = args[0];

            try {
                URL url = new URL("url");
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                /* token call */
                String urlParameters = "token=" + auth_token_string ;

                connection.setRequestMethod("POST");
                connection.setDoOutput(true);
                DataOutputStream dStream = new DataOutputStream(connection.getOutputStream());

                dStream.writeBytes(urlParameters);
                dStream.flush();
                dStream.close();

                InputStream in = connection.getInputStream();

                BufferedReader reader = new BufferedReader(new InputStreamReader(in,"iso-8859-1"),8);
                StringBuffer buffer = new StringBuffer();

                String line = "";
                while ((line = reader.readLine()) != null) {
                    buffer.append(line).append("\n");
                }
                reader.close();
                connection.disconnect();
                JSONObject jsonObj = null;

                jsonObj = new JSONObject(buffer.toString().trim());

                /* status:ok, lessons: xxxx <-- there are two object arrays. */

                JSONArray classes = null;
                classes = jsonObj.getJSONArray("lessons");

                // looping through All Contacts
                for (int i = 0; i < classes.length(); i++) {
                    JSONObject c = classes.getJSONObject(i);

                    prgmNameList.add("lesson_" + c.getString("id"));
                    caseList.add(c.getString("course"));
                    dateList.add(c.getString("date"));
                }
                return "Load Complete";
            }
            catch(Exception e) {
                Log.e("ERROR", e.getMessage(), e);
                return null;
            }
        }

        protected void onPostExecute(String response) {

            if(response == null) {
                response = "THERE WAS AN ERROR";
            }
            //progressBar.setVisibility(View.GONE);
            Log.i("INFO", response);
            if (pd != null) {
                pd.dismiss();
            }
            responseView.setText(response);
        }
    }


    public void classroom_enter(String room_name) {
        somefunction();
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getActivity().setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
    }


    @Override
    public void onResume() {
        super.onResume();
        SharedPreferences settings = PreferenceManager
                .getDefaultSharedPreferences(getContext());
        String auth_token_string = settings.getString("token", ""/*default value*/);
        this.onCreate(null);
    }


    @Override
    public void onDetach() {
        //close the connection when the fragment is detached, so the streams are not open.
        super.onDetach();
        if (skylinkConnection != null && connected) {
            skylinkConnection.disconnectFromRoom();
            skylinkConnection.setLifeCycleListener(null);
            skylinkConnection.setMediaListener(null);
            skylinkConnection.setRemotePeerListener(null);
            connected = false;
            audioRouter.stopAudioRouting(getActivity().getApplicationContext());
        }
        this.onCreate(null);
    }
}

XML Layout for VideoCallFragment

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/ll_video_call"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/ll_self_video"
        android:orientation="horizontal"
        >

        <EditText
            android:id="@+id/et_room_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="Click to Reload"
            android:textAppearance="?android:attr/textAppearanceMedium"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/mute_audio"
            android:id="@+id/toggle_audio"
            android:layout_weight="1"
            android:visibility="gone"
            />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/mute_video"
            android:id="@+id/toggle_video"
            android:layout_weight="1"
            android:visibility="gone"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="New Text"
            android:id="@+id/responseView" />

    </LinearLayout>

    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/listView_classroom"
        android:layout_gravity="center_horizontal" />


</LinearLayout>

XML layout for mainactivity

<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- As the main content view, the view below consumes the entire
         space available using match_parent in both dimensions. -->
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <!-- android:layout_gravity="start" tells DrawerLayout to treat
         this as a sliding drawer on the left side for left-to-right
         languages and on the right side for right-to-left languages.
         If you're not building against API 17 or higher, use
         android:layout_gravity="left" instead. -->
    <!-- The drawer is given a fixed width in dp and extends the full height of
         the container. -->


    <fragment
        android:id="@+id/navigation_drawer"
        android:name="com.example.sungpah.sungpahfirst.NavigationDrawerFragment"
        android:layout_width="@dimen/navigation_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        tools:layout="@layout/fragment_navigation_drawer"/>

</android.support.v4.widget.DrawerLayout>

I tried to put as detail as possible for others to easily see and refer once the answer is posted! Please help me!!

However the final line didn't work and says "Cannot resolve method notifyDatasetChanged();

That's because the method signature is notifyDataSetChanged() with a capital S.

However the data was not populated after loading is done.

That's because the adapter (and consequently the ListView ) is unaware that its data has been updated.

  • Give your VideoCallFragment a reference to the adapter:

     private CustomAdapter adapter; 
  • Set this adapter reference

      final ListView lv=(ListView) rootView.findViewById(R.id.listView_classroom); adapter = new CustomAdapter(getActivity(), prgmNameList, dateList, caseList); lv.setAdapter(adapter); 
  • call notifyDataSetChanged() on the adapter in your AsyncTask after all the data is loaded:

      // looping through All Contacts for (int i = 0; i < classes.length(); i++) { JSONObject c = classes.getJSONObject(i); prgmNameList.add("lesson_" + c.getString("id")); caseList.add(c.getString("course")); dateList.add(c.getString("date")); } adapter.notifyDataSetChanged(); return "Load Complete"; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM