在操作栏中的Android用户名第一次加载页面时不显示

问题描述:

您好我对Android非常陌生,我在将用户名(通过使用Web服务检索到)放入操作栏时遇到了一些问题。在操作栏中的Android用户名第一次加载页面时不显示

问题是,当我第一次进入我想要显示用户名的页面时,用户名不显示并显示为'null'。它仅在第二次加载页面时显示(即它仅在我转到其他页面时才会显示,然后返回到我要在其中显示用户名的页面)。

我想要在操作栏中显示用户名,即使第一次加载页面,但我不知道问题是什么。

有人可以帮我解决这个问题吗? 非常感谢您提前。

这里是我的代码:

在 '菜单',我在一个项目添加了一个机器人:actionViewClass = “android.widget.TextView”

<item 
    android:id="@+id/viewusername" 
    android:orderInCategory="1" 
    android:title="@+id/viewusername" 
    android:showAsAction="always" 
    android:actionViewClass="android.widget.TextView"/> 

要使的动作条内部用户名,我已经使用了onPrepareOptionsMenu方法:

@Override 
    public boolean onPrepareOptionsMenu(Menu menu) 
    { 

     MenuItem menuItem = menu.findItem(R.id.viewusername); 
     TextView showusername1 = (TextView) menuItem.getActionView(); 
     showusername1.setText(String.valueOf(username)); 

     return super.onPrepareOptionsMenu(menu); 
    } 

这是米ethod我用来检索Web服务的用户名(我已经使用了事件处理程序):

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

     setContentView(R.layout.fragment_dashboard); 
     Button incident = (Button) findViewById(R.id.CreateNewIncidentButton); 
     SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode 
     Editor editor = pref.edit(); 
     Bundle extras = getIntent().getExtras(); 
     if (extras != null) { 
      name = extras.getString("ID"); 
     } 

     incident.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) {   

     // Switching to Register screen   
     Intent i = new Intent(getApplicationContext(), CreateIncident.class);   
     startActivity(i);   
     }   
     });    
     Button request = (Button) findViewById(R.id.CreateNewRequestButton);   
     request.setOnClickListener(new View.OnClickListener() {    
     public void onClick(View v) { 

     // Switching to Create new request screen   
     Intent i = new Intent(getApplicationContext(), CreateRequest.class);  
     startActivity(i);   
     }   
     });    
     Button queue = (Button) findViewById(R.id.ViewMyTicketsButton);    
     queue.setOnClickListener(new View.OnClickListener() {   
     public void onClick(View v) { 

     // Switching to Register screen   
     Intent i = new Intent(getApplicationContext(), ViewMyTickets.class);  
     startActivity(i); 
     }  
     }); 




     getUsersName(); 
     } 

     public void getUsersName() {   
        methodName ="getUsersCombo"; 
      VectorString getUsersCombo = new VectorString(); //creates a new instance of VectorString 
      String[] usersCom = { "combo_name"}; //array of values 

       for (String s : usersCom) { //adds strings to getTicketInfo    
       getUsersCombo.add(s); 

       } 

     EventHandlerDashboard handler2 = new EventHandlerDashboard(this); 
     USD_WebService usdw2 = new USD_WebService(handler2,"http://dsl-116040f.datacom.co.nz:8080/axis/services/USD_R11_WebService?WSDL",60); 

     SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode 
     Editor editor = pref.edit(); 
     int usersSid = pref.getInt("sid",0); 
     String username = pref.getString("username",""); 

     try { 

     //adds all the values to the web service call 
     usdw2.doSelectAsync(usersSid, "cnt", "userid="+"'"+username+"'", -1, getUsersCombo); 

     } catch (Exception e) {  

     e.printStackTrace();      
     }      
     } 


     public void receiveResults(String result7){ 
      try { 
       DocumentBuilderFactory dbf = 
        DocumentBuilderFactory.newInstance(); 
       DocumentBuilder db = dbf.newDocumentBuilder(); 
       InputSource is = new InputSource(); 
       is.setCharacterStream(new StringReader(result7)); 

       Document doc = db.parse(is); 
       NodeList nodes = doc.getElementsByTagName("UDSObject"); 

       // iterate the employees 
       for (int i = 0; i < nodes.getLength(); i++) { 
        Element element = (Element) nodes.item(i); 

        NodeList name = element.getElementsByTagName("AttrName"); 
        Element line = (Element) name.item(0); 
        System.out.println("ID: " + getCharacterDataFromElement(line)); 

        NodeList title = element.getElementsByTagName("AttrValue"); 
        line = (Element) title.item(0); 
        System.out.println("ID Value: " + getCharacterDataFromElement(line)); 
        userID = getCharacterDataFromElement(line); 
      username= "Welcome, "+userID; 

       } 
      } 
      catch (Exception e) { 
       e.printStackTrace(); 
      } 

     System.out.println("users comboname"+result7); 

     } 
     public static String getCharacterDataFromElement(Element e) { 
      Node child = e.getFirstChild(); 
      if (child instanceof CharacterData) { 
       CharacterData cd = (CharacterData) child; 
       return cd.getData(); 
      } 
      return "?"; 
     } 

注:当它在布局的TextView的使用,但它有问题,这种方法工作完全正常,当我尝试在操作栏中使用它。

更新: 它现在:

@Override 
    public boolean onPrepareOptionsMenu(Menu menu) 
    { 

     MenuItem menuItem = menu.findItem(R.id.viewusername); 
     TextView showusername1 = (TextView) menuItem.getActionView(); 
     showusername1.setText(usersname==null?"":String.valueOf(usersname)); 

     return super.onPrepareOptionsMenu(menu); 

    } 

而且

  getUsersName(); 
     } 

     public void getUsersName() {   
        methodName ="getUsersCombo"; 
      VectorString getUsersCombo = new VectorString(); //creates a new instance of VectorString 
      String[] usersCom = { "combo_name"}; //array of values 

       for (String s : usersCom) { //adds strings to getTicketInfo    
       getUsersCombo.add(s); 

       } 

     EventHandlerDashboard handler2 = new EventHandlerDashboard(this); 
     USD_WebService usdw2 = new USD_WebService(handler2,"http://dsl-116040f.datacom.co.nz:8080/axis/services/USD_R11_WebService?WSDL",60); 

     SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode 
     Editor editor = pref.edit(); 
     int usersSid = pref.getInt("sid",0); 
     username = pref.getString("username",""); 


     try { 

     //adds all the values to the web service call 
     usdw2.doSelectAsync(usersSid, "cnt", "userid="+"'"+username+"'", -1, getUsersCombo); 

     } catch (Exception e) {  

     e.printStackTrace();      
     }      

     } 






     public void receiveResults(String result7){ 
      try { 
       DocumentBuilderFactory dbf = 
        DocumentBuilderFactory.newInstance(); 
       DocumentBuilder db = dbf.newDocumentBuilder(); 
       InputSource is = new InputSource(); 
       is.setCharacterStream(new StringReader(result7)); 

       Document doc = db.parse(is); 
       NodeList nodes = doc.getElementsByTagName("UDSObject"); 

       // iterate the employees 
       for (int i = 0; i < nodes.getLength(); i++) { 
        Element element = (Element) nodes.item(i); 

        NodeList name = element.getElementsByTagName("AttrName"); 
        Element line = (Element) name.item(0); 
        System.out.println("ID: " + getCharacterDataFromElement(line)); 

        NodeList title = element.getElementsByTagName("AttrValue"); 
        line = (Element) title.item(0); 
        System.out.println("ID Value: " + getCharacterDataFromElement(line)); 
        userID = getCharacterDataFromElement(line); 
        usersname = "Welcome, "+userID; 

       } 
      } 
      catch (Exception e) { 
       e.printStackTrace(); 
      } 

     System.out.println("users comboname"+result7); 

     invalidateOptionsMenu(); // This works on Android 3.x devices only 


     } 
     public static String getCharacterDataFromElement(Element e) { 
      Node child = e.getFirstChild(); 
      if (child instanceof CharacterData) { 
       CharacterData cd = (CharacterData) child; 
       return cd.getData(); 
      } 
      return "?"; 
     } 

呼叫invalidateOptionsMenu()一旦你找回用户名强制调用onPrepareOptionsMenu()

此外,当你调用String username = pref.getString("username","");你创建一个局部变量。而在onPrepareOptionsMenu上,您似乎正在使用字段。从声明中删除“字符串”,以便使用字段而不是变量。

从我所看到的您的用户名被加载在getUsersName();。所以可以肯定地说,在这一行之后,字段username填充了真正的用户名。请致电invalidateOptionsMenu();强制该活动再次创建optionsMenu。这将再次调用onPrepareOptionsMenu()并将用用户名填充TextView。

+0

能否请你告诉我怎么可以使用invalidateOptionsMenu()?谢谢 – user3810850 2014-09-26 09:52:39

+0

'getUsersName();'call'invalidateOptionsMenu();''后面。还要确保'onPrepareOptionsMenu'上的'String.valueOf(username)'指向一个字段。所以我建议你把'String username = pref.getString(“username”,“”);'改为'username = pref.getString(“username”,“”);' – 2014-09-26 10:06:20

+0

谢谢你的作品!我把invalidateOptionsMenu();在receiveResults(String result7)之后,因为这是我想要调用的。但在显示用户名之前它仍然显示'null'。你知道我该如何解决这个问题吗? – user3810850 2014-09-26 11:17:37

我认为这可能是因为您正在调用异步调用Web服务器来检索数据。这意味着虽然该呼叫在异步线程中处理,但应用程序的生命周期将继续onPrepareOptionsMenuusername变量被填充之前被调用。所以,当调用onPrepareOptionsMenu时,username仍然是""

您可以尝试通过AsyncTask代替异步线程。 AsyncTask将允许您在从Web服务器的onPostExecute方法返回数据之后,在UI线程上执行一些操作。

您可以使用onPostExecute修改操作栏。只要数据不从Web服务器返回,您可能会在操作栏上显示某种加载器。当它是,那么'onPostExecute'将更新acrion栏。这也可以让你捕捉从Web服务器获取数据时可能遇到的任何故障(低/没有互联网连接,断开连接的服务器以及没有连接的服务器),并建议用户“此刻你不能检索他的用户名”。您可以通过捕获网络异常或/并在请求中添加计时器来实现此目的。

这里有一些链接,引导您完成此:

AsyncTask explained

AsyncTask example (Vogella)