0

在过去的几天里,我实现了一个带有选项卡和片段的 ActionBar。

在进一步开发之前,我想问一下我的代码到目前为止是否是最优的?还是有任何失败或“不是最佳解决方案”?

代码来了,首先是 MainActivity:

public class MainActivity extends FragmentActivity 

public static int currentPos;

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    ActionBar actionBar = getActionBar();

    Tab tabDashBoard = actionBar.newTab();
    tabDashBoard.setText("Dashboard");
    TabListener<DashBoardFragment> tabListenerDashBoard = new TabListener<DashBoardFragment>(this,"Dashboard", DashBoardFragment.class);
    tabDashBoard.setTabListener(tabListenerDashBoard);
    actionBar.addTab(tabDashBoard);

    Tab tabSuche = actionBar.newTab();
    tabSuche.setText("Suche");
    TabListener<SucheFragment> tabListenerSuche = new TabListener<SucheFragment>(this,"Suche",SucheFragment.class);
    tabSuche.setTabListener(tabListenerSuche);
    actionBar.addTab(tabSuche);

    Tab tabMap = actionBar.newTab();
    tabMap.setText("Map");
    TabListener<MapFragment> tabListenerMap = new TabListener<MapFragment>(this,"Map",MapFragment.class);
    tabMap.setTabListener(tabListenerMap);
    actionBar.addTab(tabMap);

    Tab tabProfil = actionBar.newTab();
    tabProfil.setText("Profil");
    TabListener<ProfilFragment> tabListenerProfil = new TabListener<ProfilFragment>(this,"Profil",ProfilFragment.class);
    tabProfil.setTabListener(tabListenerProfil);
    actionBar.addTab(tabProfil);

    Tab tabNachrichten = actionBar.newTab();
    tabNachrichten.setText("Nachrichten");
    TabListener<NachrichtenFragment> tabListenerNachrichten = new TabListener<NachrichtenFragment>(this,"Nachrichten",NachrichtenFragment.class);
    tabNachrichten.setTabListener(tabListenerNachrichten);
    actionBar.addTab(tabNachrichten);


    //actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);  
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);    
    actionBar.setDisplayShowHomeEnabled(false);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setDisplayShowCustomEnabled(false);

     if( savedInstanceState != null ){
         actionBar.setSelectedNavigationItem(savedInstanceState.getInt("tabState"));
     }
}

private class TabListener<T extends Fragment> implements ActionBar.TabListener
{
    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    public TabListener(Activity activity,String tag,Class<T> clz) {
         mActivity = activity;
         mTag = tag;
         mClass = clz; 
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) 
    {
        currentPos = tab.getPosition();
        Fragment prevFragment;
        FragmentManager fm = mActivity.getFragmentManager();
        prevFragment = fm.findFragmentByTag(mTag); 
        if (prevFragment != null) { 
            mFragment = prevFragment; 
        } // previous Fragment management

        // Check if the fragment is already initialized
        if(mFragment == null){
            // If not, instantiate and add it to the activity:
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment,mTag);
        }else{
            // If it exists, simply attach it in order to show it:
            ft.attach(mFragment);
        }   
     }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) 
    {
        currentPos = tab.getPosition();
        if(mFragment != null){
             // Detach the fragment, because another one is being attached:
             ft.detach(mFragment);
        }else{
            // If not, instantiate and add it to the activity:
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment,mTag);
        }
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) 
    {
         // User selected the already selected tab. Usually do nothing. 
    }   
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("tabState", currentPos);
}   

现在例如 SucheFragment 类:

public class SucheFragment extends Fragment {

Activity currentActivity = getActivity();
ListView listView;
LayoutInflater inflaterT;

// ArrayList of type "Person". We are making not a list of string, sondern eine list of persons
ArrayList<Person> arrayOfWebData = new ArrayList<Person>();

class Person{
    public String person_id;
    public String name;
    public String birthday;
    public String favorite_color;
    public String profilbild;
}

// This is our new Adapter:
FancyAdapter aa = null;

// For each row we returned until we use the array to create our person obj
static ArrayList<String> resultRow;

@Override

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

        View view = inflater.inflate(R.layout.suche, container, false);
        inflaterT = inflater;
        listView = (ListView) view.findViewById(R.id.listView1);
        new getJson().execute("String");    
        return view;    
}

// JSON Response Example
private class getJson extends AsyncTask<String, String, JSONArray>
{
    @Override
    protected JSONArray doInBackground(String... params) 
    {
        String result = "";
        try{
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("xxxxxxxxxxx");
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            InputStream webs = entity.getContent();
            // Convert Response to String:
            try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(webs,"iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;

                while((line = reader.readLine()) != null){
                    sb.append(line+ "\n");  
                }
                webs.close();
                result = sb.toString(); 
            }catch(Exception e){
                e.printStackTrace();
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        try{
            JSONArray jArray = new JSONArray(result);
            for(int i = 0;i < jArray.length();i++)
            {
                // Get our object, this is on persons data:
                JSONObject json_data = jArray.getJSONObject(i);
                // Create a new person:
                Person resultRow = new Person();
                // Set thats persons attributes:
                resultRow.person_id = json_data.getString("id");
                resultRow.name = json_data.getString("name");
                resultRow.favorite_color = json_data.getString("favorite_color");
                resultRow.birthday = json_data.getString("birthday");
                resultRow.profilbild = json_data.getString("profilbild");
                arrayOfWebData.add(resultRow);
            }   
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }
    protected void onPreExecute() {
         super.onPreExecute();

         Context context = getActivity();
         CharSequence text = "Lade Mitglieder";
         int duration = 5000;

         Toast toast = Toast.makeText(context, text, duration);
         toast.show();
    }
    @Override
    protected void onPostExecute(JSONArray result) {
        super.onPostExecute(result);
        populateListView(result);

    }       
}

public void populateListView(JSONArray result)
{
    final ListView myListView = (ListView) listView;
    // Initialize FancyAdapter object:
    aa = new FancyAdapter();
    myListView.setAdapter(aa);  

    myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) 
        {
            // Get Person "behind" the clicked item
            Person p = (Person) myListView.getItemAtPosition(position);

            // Log the fields to check if we got the info we want
            Log.i("SomeTag", "Persons name: " + p.name);
            Log.i("SomeTag", "Persons id : " + p.person_id);

           Intent i = new Intent(getActivity(),ProfilAnsehenActivity.class);
           i.putExtra("mitglied_id", p.person_id);
           i.putExtra("mitglied_benutzername", p.name);
           i.putExtra("profilbild", p.profilbild);
           startActivity(i);
        }
    });
}

class FancyAdapter extends ArrayAdapter<Person>
{
    FancyAdapter(){
        super(getActivity(),android.R.layout.simple_list_item_1,arrayOfWebData);
        //imageLoader = new ImageLoader(MainActivity.this);
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if(convertView == null){
            LayoutInflater inflater = inflaterT;
            convertView = inflater.inflate(R.layout.row3, null);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder); 
        }else{
            holder = (ViewHolder)convertView.getTag();
        }
        holder.populateFrom(arrayOfWebData.get(position));
        return convertView; 
    }
}

class ViewHolder
{
    public TextView name = null;
    public TextView birthday = null;
    public TextView favorite_color = null;
    public ImageView profilbild = null;
    //public ImageLoader imageLoader;
    ImageLoader imageLoader = new ImageLoader(getActivity());

    ViewHolder(View row){
        name = (TextView)row.findViewById(R.id.name);
        birthday = (TextView)row.findViewById(R.id.birthday);
        favorite_color = (TextView)row.findViewById(R.id.favorite_color);
        profilbild = (ImageView)row.findViewById(R.id.imageView1);  
    }
    // Notice we have to change our populateFrom() to take an argument of type "Person"
    void populateFrom(Person r){
        name.setText(r.name);
        birthday.setText(r.birthday);
        favorite_color.setText(r.favorite_color);
        imageLoader.DisplayImage(r.profilbild, profilbild); 
    }   
}   

可以从上面的“SucheFragment”中启动一个活动吗?最后是 ProfilAnsehenActivity: (在单击 ListView 项目时调用):

public class ProfilAnsehenActivity extends Activity implements ActionBar.TabListener {


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


    ActionBar actionBar = getActionBar();

    /*Tab tabDashBoard = actionBar.newTab();
    tabDashBoard.setText("Profil");
    tabDashBoard.setTabListener(this);
    actionBar.addTab(tabDashBoard);

    Tab tabDashBoard2 = actionBar.newTab();
    tabDashBoard2.setText("Fotos");
    tabDashBoard2.setTabListener(this);
    actionBar.addTab(tabDashBoard2);

    Tab tabDashBoard3 = actionBar.newTab();
    tabDashBoard3.setText("Nachricht senden");
    tabDashBoard3.setTabListener(this);
    actionBar.addTab(tabDashBoard3);*/

    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);    
    actionBar.setDisplayShowHomeEnabled(false);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setDisplayShowCustomEnabled(false);



    Intent intent = getIntent();
    String mitglied_benutzername = intent.getStringExtra("mitglied_benutzername");
    String mitglied_id = intent.getStringExtra("mitglied_id");
    String profilbild = intent.getStringExtra("profilbild");

    TextView benutzername = (TextView)findViewById(R.id.textViewBenutzername);
    benutzername.setText(mitglied_benutzername);

    TextView mitglied_idV = (TextView)findViewById(R.id.textViewMitgliedId);
    mitglied_idV.setText("Mitglied-ID:" +mitglied_id);

    ImageView imageV = (ImageView)findViewById(R.id.imageView2);

    ImageLoader imageLoader = new ImageLoader(ProfilAnsehenActivity.this);
    imageLoader.DisplayImage(profilbild, imageV);       
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_profil_ansehen, 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 onTabReselected(Tab tab, FragmentTransaction ft) {
    // TODO Auto-generated method stub

}

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    // TODO Auto-generated method stub

}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    // TODO Auto-generated method stub

}

你怎么看 ?我有什么“误解”吗?顺便说一下:

当我将方向从纵向更改为横向时,再次调用 getJson 方法并再次加载来自互联网的 json 数据......如何防止“SucheFragment”再次下载 json 数据?我想显示与方向更改之前相同的数据...

问候,朱利安

4

3 回答 3

0

至少,您必须创建Activityas的所有内部类static,因为非静态内部类会在设备旋转时引起内存喜欢。

AsyncTask此外,用于网络的东西也不是一个最好的主意,最好使用IntentService+SQLite方法。例如,您可以查看来自 Google I/O 的有关 REST 最佳实践的视频

我想显示与方向更改之前相同的数据...

您可以在片段中保存标志,并且new getJson().execute("String");只调用一次。但是记住AsyncTask不是网络东西的最佳场所。

标记代码示例(在您的片段中):

....
private boolean isAlreadyRunned = fasle;

.... (onCreateView())
if (!isAlreadyRunned){
    new getJson().execute("String");
}

...(getJson)
 arrayOfWebData.add(resultRow);
 isAlreadyRunned = true;

类似的东西)))

于 2013-01-09T05:19:10.753 回答
0

我现在添加了标志“private boolean jsonDataLoaded = false;”

当应用程序首次加载数据时,我将其设置为 true。然后在 onCreateView() 我检查标志是否为假,- 如果是,- 不要跳入 geJson():

当调用 getJson() 时,我将 jsonDataLoaded 设置为 TRUE。

它的行为类似于expexted:1)加载jsonData并将flag设置为TRUE 2)切换到其他选项卡并返回SucheFragment后,flag为TRUE,并且没有加载数据:

但是:数据没有加载(正确的行为), 但是 ListView 没有填充之前收到的数据。

这里是SucheFragment的代码:

public class SucheFragment extends Fragment {

Activity currentActivity = getActivity();
ListView listView;
LayoutInflater inflaterT;

// ArrayList of type "Person". We are making not a list of string, sondern eine list of persons
ArrayList<Person> arrayOfWebData = new ArrayList<Person>();

class Person{
    public String person_id;
    public String name;
    public String birthday;
    public String favorite_color;
    public String profilbild;
}

// This is our new Adapter:
FancyAdapter aa = null;

// For each row we returned until we use the array to create our person obj
static ArrayList<String> resultRow;

// If true,- the JSON data has been loaded:
private boolean jsonDataLoaded = false;

@Override
// Create and return the view hierarchy associated with the fragment
// The System invokes this method when its time for the fragment to create its layout
// This method must return a View that is the ROOT of your fragments layout
// Parameter "container": Is the parent of the View (e.g LinearLayout etc)
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        // Parameter: 
        //      1) RESOURCE:        ID for an XML Layout Resource
        //      2) ROOT:            An object that provides a set of LayoutParams values for root of the returned hierarchy (if 3.Parameter is false)
        //      3) attachToRoot:    Whether the inflated hierarchy should be attached to the root parameter
        //                          If ROOT, root is only used to create the correct subclass of LayoutParams for the root view in the XML.
        //                          Wenn FALSE,- prevents the inflater from automatically attaching the inflated view hierarchy to the parent container
        View view = inflater.inflate(R.layout.suche, container, false);
        inflaterT = inflater;
        listView = (ListView) view.findViewById(R.id.listView1);

        Log.i("TEST","LOADED "+jsonDataLoaded);

        if(!jsonDataLoaded){
            new getJson().execute("String");    
        }




        return view;    
}

// JSON Response Example
private class getJson extends AsyncTask<String, String, JSONArray>
{
    @Override
    protected JSONArray doInBackground(String... params) 
    {
        String result = "";
        try{
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("xxx");
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            InputStream webs = entity.getContent();
            // Convert Response to String:
            try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(webs,"iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;

                while((line = reader.readLine()) != null){
                    sb.append(line+ "\n");  
                }
                webs.close();
                result = sb.toString(); 
            }catch(Exception e){
                e.printStackTrace();
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        try{
            JSONArray jArray = new JSONArray(result);
            for(int i = 0;i < jArray.length();i++)
            {
                // Get our object, this is on persons data:
                JSONObject json_data = jArray.getJSONObject(i);
                // Create a new person:
                Person resultRow = new Person();
                // Set thats persons attributes:
                resultRow.person_id = json_data.getString("id");
                resultRow.name = json_data.getString("name");
                resultRow.favorite_color = json_data.getString("favorite_color");
                resultRow.birthday = json_data.getString("birthday");
                resultRow.profilbild = json_data.getString("profilbild");
                arrayOfWebData.add(resultRow);

            }   
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }
    protected void onPreExecute() {
         super.onPreExecute();

         Context context = getActivity();
         CharSequence text = "Lade Mitglieder";
         int duration = 5000;

         Toast toast = Toast.makeText(context, text, duration);
         toast.show();
    }
    @Override
    protected void onPostExecute(JSONArray result) {
        super.onPostExecute(result);
        populateListView(result);
        jsonDataLoaded = true;

    }       
}

public void populateListView(JSONArray result)
{
    final ListView myListView = (ListView) listView;
    // Initialize FancyAdapter object:
    aa = new FancyAdapter();
    myListView.setAdapter(aa);  

    myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) 
        {
            // Get Person "behind" the clicked item
            Person p = (Person) myListView.getItemAtPosition(position);

            // Log the fields to check if we got the info we want
            Log.i("SomeTag", "Persons name: " + p.name);
            Log.i("SomeTag", "Persons id : " + p.person_id);

           Intent i = new Intent(getActivity(),ProfilAnsehenActivity.class);
           i.putExtra("mitglied_id", p.person_id);
           i.putExtra("mitglied_benutzername", p.name);
           i.putExtra("profilbild", p.profilbild);
           startActivity(i);
        }
    });
}

class FancyAdapter extends ArrayAdapter<Person>
{
    FancyAdapter(){
        super(getActivity(),android.R.layout.simple_list_item_1,arrayOfWebData);
        //imageLoader = new ImageLoader(MainActivity.this);
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if(convertView == null){
            LayoutInflater inflater = inflaterT;
            convertView = inflater.inflate(R.layout.row3, null);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder); 
        }else{
            holder = (ViewHolder)convertView.getTag();
        }
        holder.populateFrom(arrayOfWebData.get(position));
        return convertView; 
    }
}

class ViewHolder
{
    public TextView name = null;
    public TextView birthday = null;
    public TextView favorite_color = null;
    public ImageView profilbild = null;
    //public ImageLoader imageLoader;
    ImageLoader imageLoader = new ImageLoader(getActivity());

    ViewHolder(View row){
        name = (TextView)row.findViewById(R.id.name);
        birthday = (TextView)row.findViewById(R.id.birthday);
        favorite_color = (TextView)row.findViewById(R.id.favorite_color);
        profilbild = (ImageView)row.findViewById(R.id.imageView1);  
    }
    // Notice we have to change our populateFrom() to take an argument of type "Person"
    void populateFrom(Person r){
        name.setText(r.name);
        birthday.setText(r.birthday);
        favorite_color.setText(r.favorite_color);
        imageLoader.DisplayImage(r.profilbild, profilbild); 
    }   
}   
于 2013-01-10T10:58:05.553 回答
0

你可以加

android:configChanges="orientation" 

在您的活动清单中,以防止再次下载 json 数据。

通过添加此行,您的 onCreate() 方法不会在方向更改时调用,因此它会显示与方向更改之前相同的数据。

但是您必须处理 UI 更改。

希望对你有帮助..

于 2013-01-09T05:09:44.433 回答