有個問題想要請教:
因是使用Json 讀取,如果name 沒有資料,想要用Toast顯示無資料, 相反的,如果name 有資料,在recyclerview會顯示資料。
但我的問題點在於,如果name 沒有任何資料,程式碼則完全沒有反應,我用name.length==null 或是 name.length==0 或是 name.length< 1 或是 name.isEmpty() 都一樣,想要知道這是為什麼??? 能不能請給我一個方向? 因我已想不出到底是為什麼?
if(Region.equals(name) & dt1.getTime() < dt2.getTime()){
Log.i("Volley12", String.valueOf(name.length()));
citymovie citymovie = new city(name,Add,Start,End,Location,Picture1,px,py);
movieList.add(citymovie);
mAdapter.notifyDataSetChanged();
if(name.length() <1){
Toast.makeText(getApplication(), "小於1",
Toast.LENGTH_LONG).show();
}
謝謝
null是一種很奇特的東西。它不是值、不是東西、什麼都沒有。
在任何應用程式上,當碰到null要很特別的小心使用。
有些程式語言,是還可以用==null來做判斷。
但有些則是不行。
有的根本沒有所謂null值。如java或javascript。
當碰到所謂不存在的值判斷。要很特別的小心。
由於不太清楚你是用什麼語言寫的。但看起來很像是java之類的。
有的根本沒有所謂null值。如java或javascript
路過問一下,星空大大為啥會說「javascript」沒有所謂的null值
由於不太清楚你是用什麼語言寫的。但看起來很像是java之類的。
Code有Log.i和Toast,應該是用Java寫Android
Yes! 是java~ 但為什麼 isEmpty()也一樣???? 真的是不懂想要求解!! 跪求拜託!!!!!
我明白你想這樣問的意思。因為實際上還是可以用 = null這樣的語法。
這個問題其實就得從名詞的解釋來看起。
實際性的null及假像性的null。
其實如果我說 undefined 因該就可以明白。
但要了解到一件事,認真來說,undefined 雖等同是 null 。但它又不是 null 。很奇妙吧。
上面我說了,這需要從名詞上來解釋了。
如將null等成一個值。那javascript就是有null。畢竟可以給值。
如將null當一種表現。那javascript就不會有null。
null是一個很奇妙的東西。你要說它是不是值?感覺像值但又不是值。
去思考這個問題看看吧。
但個人有個人的解釋。這個問題早在10多年前就曾經有過很大的爭議。
php的許多函數,也因為null這個東西變動過許多解釋及應用。
現在大約是固定了。同一解釋。
可能只有比較老的人才會比較過null吧。
我覺得樓主在取得JSON的時候
可以用Has去判斷有沒有「name」這個Key存在
如果name 不存在,給name一個值
避免null跟undefined或甚至像星空大大說得連null都沒有
如果可以的話附上JSON的範例Sample
這樣會更清楚問題在哪邊
這個給你參考,你研究看看:
https://stackoverflow.com/questions/17487205/how-to-check-if-a-json-key-exists
Shihjoanna
我剛上面說了php有部份的函數,也為了null改變很多次解釋。
如isEmpty。在許多年前,並未將null視為是空值。
因為它不是值,一種不存在的觀念。不該將其視為空值。
畢竟也無法比較。在程式中不存在就是不存在。這也就跟不能除於0這樣的觀念有點類同。
一直到最後,其實到現在還是有部份的應用。還是認為null本來就不能當比較。其中一例就是sql了。
在php則是已經將null當成isEmpty。(但可以調整ini視為不存在)
在 java裏,很好玩的是將null列成一種特別的值。
它不屬於任何型別,但它可以存在任何型別上。
宣告時不會有事,但使用它則常會發生空指標異常的問題。
所以使用它要很小心。
謝謝通靈亡! 但我想還是要先說一下:我是真的已不知道問題在哪,才把程式碼貼出來~ 希望不要引起不必要誤會~~
我的流程如下:
下方附上我的程式碼:
public class Main2Activity extends AppCompatActivity {
RecyclerView recyclerView;
private List<citymovie> movieList = new ArrayList<>();
private citymovieadapter mAdapter;
String name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Intent intent = this.getIntent();
name = intent.getStringExtra("name");
// Toast.makeText(this, name, Toast.LENGTH_SHORT).show();
recyclerView = (RecyclerView) findViewById(R.id.cityactivity);
mAdapter = new citymovieadapter(movieList);
recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
// layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(mAdapter);
new TransTask1().execute("https://gis.taiwan.net.tw/XMLReleaseALL_public/activity_C_f.json");
}
class TransTask1 extends AsyncTask<String, Void, String> {
StringBuffer json = new StringBuffer();
@Override
protected String doInBackground(String... params) {
try {
URL url = new URL(params[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream is = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = br.readLine();
while (line != null) {
json.append(line);
line = br.readLine();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return json.toString();
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
JSONObject jonObject = null;
try {
jonObject = new JSONObject(s.toString());
JSONArray contacts = jonObject.getJSONObject("XML_Head").getJSONObject("Infos").getJSONArray("Info");
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
String sna = c.getString("Name");
String Region = c.getString("Region");
String Add = c.getString("Add");
String Start1 = c.getString("Start");
String Location = c.getString("Location");
String px = c.getString("Px");
String py = c.getString("Py");
String Description = c.getString("Description");
String Start = Start1.substring(0,10);
String Picture1 = c.getString("Picture1");
String Picture2 = c.getString("Picture2");
String Picture3 = c.getString("Picture3");
String End1 = c.getString("End");
String End = End1.substring(0,10);
// Log.i("Volley", sna);
Calendar mCal = Calendar.getInstance();
String dateformat = "yyyy-MM-dd";
SimpleDateFormat df = new SimpleDateFormat(dateformat);
String today = df.format(mCal.getTime());
Date dt1 = df.parse(today);
Date dt2 = df.parse(End);
if(Region.equals(name) & dt1.getTime() < dt2.getTime()){
Log.i("Volley12", String.valueOf(sna.length()));
citymovie citymovie = new citymovie(sna,Add,Start,End,Location,Picture1,px,py,Picture2,Picture3,Description);
movieList.add(citymovie);
mAdapter.notifyDataSetChanged();
}
}
} catch (JSONException | ParseException e) {
e.printStackTrace();
}
}
}
}
浩瀚星空 以前從沒想過null 竟然是這樣子~ 但經過這一次之後,我應該會儘量不使用null的方式~
這邊邏輯感覺怪怪的:
if(Region.equals(name) & dt1.getTime() < dt2.getTime()) {
(...省略...)
if(name.length() <1) {}
}
如果資料的日期已過期,照理來說應該不會進入到 if(Region.equals(name) & dt1.getTime() < dt2.getTime())
那麼if(name.length() <1) 根本就不會有反應
另外,你的name是從intent帶過來的:
Intent intent = this.getIntent();
name = intent.getStringExtra("name");
想問name跟JSON的關係在哪邊?
這兩點是我看完比較疑惑的地方
通靈亡
name: 是由前一頁使用者按台北市的選項,把"台北市"這個值傳過來。
這時再將Json 的資料全部載入
再將name(台北市)這個值跟觀光局提供的json 裡面的 Region再做比對Region.equals(name),Region 跟name 兩者要等於,且日期不能是已過期的。
但不明白您這一句: "那麼if(name.length() <1) 根本就不會有反應"
因我的想法是:如果name 沒有東西,那它不是應該繼續執行下一行的程式嗎? 就是我最原本Toast.makeText(getApplication(), "小於1",
Toast.LENGTH_LONG).show();
還是我哪邊的想法不對?
name: 是由前一頁使用者按台北市的選項,把"台北市"這個值傳過來。
再將name(台北市)這個值跟觀光局提供的json 裡面的 Region再做比對
因我的想法是:如果name 沒有東西,那它不是應該繼續執行下一行的程式嗎
你點出重點了
既然你的name是從前一頁帶過來的
那麼name不管如何都會有值吧
但不明白您這一句: "那麼if(name.length() <1) 根本就不會有反應"
你覺得當 if(Region.equals(name) & dt1.getTime() < dt2.getTime()) 不成立的時候,會執行到裡面的if(name.length() <1) 嗎?
// 條件符合的時候,將資料加到清單
if(Region.equals(name) & dt1.getTime() < dt2.getTime()){
Log.i("Volley12", String.valueOf(sna.length()));
citymovie citymovie = new citymovie(sna,Add,Start,End,Location,Picture1,px,py,Picture2,Picture3,Description);
movieList.add(citymovie);
mAdapter.notifyDataSetChanged();
}
依照你的程式碼
當符合條件,將資料加到movieList
如果說這個縣市完全沒資料
應該是for全部做完後,當 movieList.size() <= 0 的時候彈出toast才對吧
謝謝大家,謝謝通靈亡浩瀚星空 謝謝您們肯耐心的講解~ 讓我有再次的學習~
問題解決了,我留下我後面的程式碼,之後的人如果也遇到相同的問題,可以參考看看
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
JSONObject jonObject = null;
try {
jonObject = new JSONObject(s.toString());
JSONArray contacts = jonObject.getJSONObject("XML_Head").getJSONObject("Infos").getJSONArray("Info");
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
String sna = c.getString("Name");
String Region = c.getString("Region");
String Add = c.getString("Add");
String Start1 = c.getString("Start");
String Location = c.getString("Location");
String px = c.getString("Px");
String py = c.getString("Py");
String Description = c.getString("Description");
String Start = Start1.substring(0,10);
String Picture1 = c.getString("Picture1");
String Picture2 = c.getString("Picture2");
String Picture3 = c.getString("Picture3");
String End1 = c.getString("End");
String End = End1.substring(0,10);
// Log.i("Volley", sna);
Calendar mCal = Calendar.getInstance();
String dateformat = "yyyy-MM-dd";
SimpleDateFormat df = new SimpleDateFormat(dateformat);
String today = df.format(mCal.getTime());
Date dt1 = df.parse(today);
Date dt2 = df.parse(End);
if(Region.equals(name) & dt1.getTime() < dt2.getTime()){
citymovie citymovie = new citymovie(sna,Add,Start,End,Location,Picture1,px,py,Picture2,Picture3,Description);
movieList.add(citymovie);
mAdapter.notifyDataSetChanged();
}
}
if(movieList.size() >=1){
Toast.makeText(getApplication(), "大於1",
Toast.LENGTH_LONG).show();
// Log.i("Volley12", String.valueOf(movieList));
}else{
Toast.makeText(getApplication(), "小於1",
Toast.LENGTH_LONG).show();
}
} catch (JSONException | ParseException e) {
e.printStackTrace();
}
}
}
}
其實我java很少會用到null。且也寫的少。
但為了null的問題。
我曾經也為了javascript特別寫了一個isset跟isnull的判斷式來用。
浩瀚星空之前的想法會一直是,當資料抓不到,那它不就是null 或是empty 或是lenth =0,但程式碼不管怎麼試,就是沒動靜~ 但經過今天您這麼一說~ 之後可能會再對java更加的努力~
Shihjoanna
總結來說,這次的問題算是程式邏輯上的錯誤,造成程式無法動作
在你的問題情境下,所謂的沒資料
應該是For迴圈過濾後
,清單為空(筆數為0)的時候
因為你撈的每個JSON當中,Region欄位一定都會有值
而name是從前一頁帶過來,也一定都會有值
所以跟null其實沒有關係
之前我朋友也是弄了老半天,一直以為問題應該是A
後來幫他看完程式碼,最後才發現問題和A沒關係
算是程式不熟的人容易卡住的狀況,寫久就習慣了。
其實我昨天這個問題解決之後,原本我覺得理想的狀態是能希望能將「無資料顯示」能夠set在Recyclerview裡面,但沒有辦法解決,後來決定,當沒資料時,就用Toast顯示 + 再將頁面轉回前一頁。 但還是很謝謝您昨天的提點~