2016年2月28日 星期日

location input problem,the number of word,the number is ok?

Another problem:the location input

1.the input that can’t resolve to a location
2.the input is not the location that the user expect,because we use zipcode,different location may have same zip code


for problem 1,if the use input the location that the server can’t resolve,it return 404.


Here is the step:



if we input the wrong city id,
it will return
{"cod":"404","message":"Error: Not found city"}


we crate a function to check


/* if we inpu the wrong city id,it will return
    * {"cod":"404","message":"Error: Not found city"}
     * so we shouluse this function to detect the cod appear,id apper that mean the cit id is wrong,than return true*/
   private boolean theCityidIsWrong(String s) throws JSONException {
       final String OWM_CODE = "cod";
       JSONObject forecastJson = new JSONObject(s);
       if (forecastJson.has(OWM_CODE)) {
           if (forecastJson.getInt(OWM_CODE) == 404) {
               return true;//city id is wrong
           }
       } else {
           return false;
       }
       return false;
   }


the full answer is here


to do more,we can show the location is not vaild on the preference summary,how?think by yourself.



Now,we want to make a custom preference view to make the input of city id is at least 3 number

The custom preference view



we want to have a custom EditTextPreference that have limited the minilength.e.g.>=3


step1 we need todefine the custom attribute



create a xml file into a res/values/attrs.xml file.


because we want to have a attribute to set the min ilength


<resources>
   <declare-styleable name="LocationEditTextPreference">
       <attr name="minLength" format="integer"/>
   </declare-styleable>
</resources>


step2 create a new class extends EditTextPreference



public class LocationEditTextPreference extends EditTextPreference {
   private int  DEFAIULT_MIN_LENGTH=5;
   private int miniLength;


   public int getMiniLength() {
       return miniLength;
   }


   public LocationEditTextPreference setMiniLength(int miniLength) {
       this.miniLength = miniLength;
       return this;
   }


   public LocationEditTextPreference(Context context, AttributeSet attrs) {
       super(context, attrs);
       //get the array that saved the typed attr
       TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.LocationEditTextPreference, 0, 0);
       //get the min length value
       try{ miniLength=a.getInteger(R.styleable.LocationEditTextPreference_minLength,DEFAIULT_MIN_LENGTH);
       }finally {
           a.recycle();
       }


   }
}

**when crate,read the mini length attr


Step 3 finally,u can use it

<com.example.android.sunshine.app.LocationEditTextPreference
       android:title="@string/pref_location_label"
       android:key="@string/pref_location_key"
       android:defaultValue="@string/pref_location_default"
       android:inputType="text"
       android:singleLine="true"
       app:minLength="6"/>

but it only can read the mini length,don’t have any effect
we want:if the inpu lenght is < the mini lenght, the ok button can’t click

The concept is:
set a listern to the edittext ,when the input change, chek the length of the input,to disable or enable the ok button

public class LocationEditTextPreference extends EditTextPreference implements TextWatcher {
   private int DEFAIULT_MIN_LENGTH = 5;
   private int miniLength;
   private EditText edt;


   public LocationEditTextPreference(Context context, AttributeSet attrs) {
       super(context, attrs);
       //get the array that saved the typed attr
       TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.LocationEditTextPreference, 0, 0);
       //get the min length value
       try {
           miniLength = a.getInteger(R.styleable.LocationEditTextPreference_minLength, DEFAIULT_MIN_LENGTH);
           Log.d("EditTextPreference", "mini is" + miniLength);
       } finally {
           a.recycle();
       }


   }


   public int getMiniLength() {
       return miniLength;
   }


   public LocationEditTextPreference setMiniLength(int miniLength) {
       this.miniLength = miniLength;
       return this;
   }


   @Override
   protected void showDialog(Bundle state) {
       super.showDialog(state);
       edt = getEditText();
       edt.addTextChangedListener(this);
   }


   @Override
   public void beforeTextChanged(CharSequence s, int start, int count, int after) {


   }


   @Override
   public void onTextChanged(CharSequence s, int start, int before, int count) {


   }


   @Override
   public void afterTextChanged(Editable s) {
       AlertDialog d = (AlertDialog)getDialog();
       Button positiveB = d.getButton(AlertDialog.BUTTON_POSITIVE);
       if(s.length()<miniLength){
           positiveB.setEnabled(false);
       }else{
           positiveB.setEnabled(true);
       }
   }

}