在过去的几天里,我已经用Tabs和Fragments实现了一个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-class:
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”中启动一个Activity吗? 最后是ProfilAnsehenActivity :(单击von一个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-Method和来自Internet的json数据 再次加载...如何防止“SucheFragment”再次下载json数据?我希望显示与方向更改之前相同的数据...
问候, 儒略
答案 0 :(得分:0)
你可以添加
android:configChanges="orientation"
在您的活动清单中,以防止再次下载json数据。
通过添加此行,您的onCreate()方法不会调用方向更改,因此它显示与方向更改之前相同的数据。
但您必须处理UI更改。
希望这会对你有帮助..
答案 1 :(得分:0)
至少,您必须将Activity
的所有内部类都设为static
,因为非静态内部类可以在设备轮换时记忆内存。
使用AsyncTask
进行网络搜索也不是最佳选择,最好使用IntentService
+ SQLite
方法。例如,您可以查看来自Google I / O的this视频,了解有关REST最佳做法的信息
我希望显示与方向更改之前相同的数据...
您可以在片段中保存标记,并且只能呼叫new getJson().execute("String");
一次。但请记住,AsyncTask
不是网络资源的最佳选择。
标记代码示例(在片段中):
....
private boolean isAlreadyRunned = fasle;
.... (onCreateView())
if (!isAlreadyRunned){
new getJson().execute("String");
}
...(getJson)
arrayOfWebData.add(resultRow);
isAlreadyRunned = true;
类似的东西)))
答案 2 :(得分:0)
我现在添加了标志“private boolean jsonDataLoaded = false;”
当应用程序首次加载数据时,我将其设置为true。 然后在onCreateView()中检查标志是否为假, - 如果是, - 不 跳进geJson():
调用getJson()时,我将jsonDataLoaded设置为TRUE。
它表现得像被驱逐: 1)加载jsonData并将flag设置为TRUE 2)更改为其他选项卡并返回SucheFragment后, 标志为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);
}
}