1

이 앱에는 단일 테이블 데이터베이스에서 CRUD 작업을 수행하는 조각이 있습니다.GoogleAPIClient on recyclerview adapter

FAB 및 recyclerview를 그리는 클래스에서 수행됩니다.

FAB는 삽입 양식이있는 alertDialog를 엽니 다.

recyclerview는 데이터베이스 행을 카드보기로 표시합니다. 각 카드보기에는 수정 버튼과 삭제 버튼이 있습니다.

편집 버튼을 누르면 편집 대화 상자가있는 경고 대화 상자가 열립니다.

데이터베이스에는 시작점과 끝점이있는 여정이 저장됩니다.

장소를 입력하거나 편집 할 때 제안 사항이 표시됩니다. 이 내가 구글 장소 웹 서비스 API를 사용하지만 GoogleApiClient 따라서 앱을하고, 잘 작동하는지

참고 내가 안드로이드에 대한 Google 지역 정보 API를 사용해야합니다 내 관심에 도착 하였다 들어

CRUD를 성공적으로 완료하고 심지어 웹 서비스에서 방향 제안을 얻습니다.

삽입 양식이 올바른 API를 사용하지만 편집 양식은 사용할 수 없었습니다. 여기

는 조각 코드 :

public class RecyclerFragment extends Fragment 
     implements AlertDialog.OnClickListener, 
     GoogleApiClient.OnConnectionFailedListener, 
     GoogleApiClient.ConnectionCallbacks { 

    private static final String TAG = "RecyclerFragment"; 
    RunDbHelper runDbHelper; // Database helper class 
    RecyclerView recyclerView; 
    RecyclerViewAdapter recyclerViewAdapter; 

    private OnOkButtonListener mCallback;  

    private GoogleApiClient mGoogleApiClient; 
    private PlaceArrayAdapter mPlaceArrayAdapter; 

    private static final int GOOGLE_API_CLIENT_ID = 0; 

    private static final LatLngBounds BOUNDS_MOUNTAIN_VIEW = new LatLngBounds(
      new LatLng(37.398160, -122.180831), new LatLng(37.430610, -121.972090)); 

    private static LatLngBounds BOUNDS_AUTOCOMPLETE; 

    public RecyclerFragment() { 
     this.mCallback = null; 
    } 

    // main activity calls this method to pass the location so it can calculate bounds for the direction suggestions 
    public void setAutocompleteBounds(LatLng centerLatLng){ 
     if (centerLatLng!= null && !centerLatLng.toString().isEmpty()){ 
      Double latSW, lngSW, lngNE, latNE; 
      latSW = centerLatLng.latitude-.5; 
      lngSW = centerLatLng.latitude-.5; 
      lngNE = centerLatLng.latitude+.5; 
      latNE = centerLatLng.latitude+.5; 
      BOUNDS_AUTOCOMPLETE = new LatLngBounds(
        new LatLng(latSW, lngSW), new LatLng(latNE, lngNE)); 
     } else { 
      BOUNDS_AUTOCOMPLETE = BOUNDS_MOUNTAIN_VIEW; 
     } 
    } 

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

     View view = inflater.inflate(R.layout.fragment_recycler, container, false); 
     try { 
      mGoogleApiClient = new GoogleApiClient.Builder(getContext()) 
        .addApi(Places.GEO_DATA_API) 
        .enableAutoManage(getActivity(), GOOGLE_API_CLIENT_ID, this) 
        .addConnectionCallbacks(this) 
        .build(); 
     } catch (Exception e) { 
      Log.i(TAG, "onCreateView: " + e); 
     } 

     mPlaceArrayAdapter = new PlaceArrayAdapter(getContext(), android.R.layout.simple_list_item_1, 
       BOUNDS_AUTOCOMPLETE, null); 

     runDbHelper = RunDbHelper.getInstance(getContext()); 
     List<RunData> mList = runDbHelper.getAllRuns(); 
     recyclerViewAdapter = new RecyclerViewAdapter(getContext(), mList); 
     recyclerView = (RecyclerView) view.findViewById(R.id.rvRunList); 
     recyclerView.setHasFixedSize(true); 
     recyclerView.setAdapter(recyclerViewAdapter); 
     recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 

     FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.fabAdd); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       // Data entry dialog to insert new runs into database 
       dialogInsertRun(); 
      } 
     }); 
     return view; 
    } 

    @Override 
    public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
    } 

    public void dialogInsertRun() { 

     // Get the Activity for layout inflater as this dialog runs inside a fragment 
     LayoutInflater inflater = LayoutInflater.from(getActivity()); 
     final View view = inflater.inflate(R.layout.dialog_new_run, null); 

     // Dialog Builder 
     AlertDialog.Builder addRunDialog = new AlertDialog.Builder(getActivity()); 
     addRunDialog.setTitle(R.string.dialog_insert_run_title) 
       .setView(view); 

     // Data entry field objects 
     final EditText runParcelEditText = (EditText) view.findViewById(R.id.new_run_parcel); 
     final AutoCompleteTextView collectAddressACTV = (AutoCompleteTextView) view.findViewById(R.id.actv_new_collect_address); 

     final EditText collectPersonEditText = (EditText) view.findViewById(R.id.new_collect_person); 
     final AutoCompleteTextView deliveryAddressACTV = (AutoCompleteTextView) view.findViewById(R.id.actv_new_delivery_address); 
     final EditText deliveryPersonEditText = (EditText) view.findViewById(R.id.new_delivery_person); 

     collectAddressACTV.setThreshold(3); 
     collectAddressACTV.setOnItemClickListener(mAutocompleteClickListener); 
     collectAddressACTV.setAdapter(mPlaceArrayAdapter); 

     deliveryAddressACTV.setThreshold(3); 
     deliveryAddressACTV.setOnItemClickListener(mAutocompleteClickListener); 
     deliveryAddressACTV.setAdapter(mPlaceArrayAdapter); 

     addRunDialog.setPositiveButton(R.string.button_positive, new DialogInterface.OnClickListener() { 

      @Override 
      public void onClick(DialogInterface dialog, int id) { 

       RunData runData = new RunData(); // POJO that holds data from database 

       runData.run_parcel = getStringOrEmpty(runParcelEditText); 
       runData.collect_person = getStringOrEmpty(collectPersonEditText); 
       runData.collect_address = getStringOrEmpty(collectAddressACTV); 
       runData.delivery_person = getStringOrEmpty(deliveryPersonEditText); 
       runData.delivery_address = getStringOrEmpty(deliveryAddressACTV); 

       // must insert at least one of the places (starting or ending point) or both 
       if (!(runData.collect_address.isEmpty() && runData.delivery_address.isEmpty())) { 

        runData = runDbHelper.insertRun(runData, getActivity()); 
        if (runData != null) { 
         cardViewMessageIsEmpty.setVisibility(View.INVISIBLE); 
         recyclerViewAdapter = new RecyclerViewAdapter(getActivity(), runDbHelper.getAllRuns()); 
         recyclerView.setAdapter(recyclerViewAdapter); 
         recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 
         mCallback.addMarkersToMap(runData); 
        } 
       } else { 
        Toast.makeText(getActivity(), R.string.dialog_insert_run_toast_nowhere, Toast.LENGTH_LONG).show(); 
       } 
      } 
     }); 

     addRunDialog.setNegativeButton(R.string.button_negative, new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int whichButton) { 
       dialog.cancel(); 
      } 
     }); 

     addRunDialog.create(); 
     addRunDialog.show(); 
    } 

    private String getStringOrEmpty(EditText editText) { 
     String mString = editText.getText().toString(); 
     mString = (mString == null || mString.isEmpty() ? "" : mString); 
     return mString; 
    } 

    @Override 
    public void onClick(DialogInterface dialogInterface, int i) { 
     //Log.d(TAG, "onClick: "); 
    } 

    @Override 
    public void onAttach(Context context) { 

     if (context instanceof OnOkButtonListener) { 
      mCallback = (OnOkButtonListener) context; // keep a reference to eula activity for interface 
     } else { 
      throw new ClassCastException(context.toString() 
        + getString(R.string.exception_onokbutton_listener)); 
     } 
     super.onAttach(context); 
    } 

    public void setCustomObjectListener(OnOkButtonListener listener) { 
     this.mCallback = listener; 
    } 

    @Override 
    public void onConnected(@Nullable Bundle bundle) { 
     mPlaceArrayAdapter.setGoogleApiClient(mGoogleApiClient); 
     Log.i(TAG, "Google Places API connected."); 
    } 

    @Override 
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
     Log.e(TAG, "Google Places API connection failed with error code: " 
       + connectionResult.getErrorCode()); 

     Toast.makeText(getContext(), 
       "Google Places API connection failed with error code:" + 
         connectionResult.getErrorCode(), 
       Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     mPlaceArrayAdapter.setGoogleApiClient(null); 
     Log.e(TAG, "Google Places API connection suspended."); 
    } 

    public interface OnOkButtonListener { 
     void addMarkersToMap(RunData runData); 
    } 

    private AdapterView.OnItemClickListener mAutocompleteClickListener 
      = new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      final PlaceArrayAdapter.PlaceAutocomplete item = mPlaceArrayAdapter.getItem(position); 
      final String placeId = String.valueOf(item.placeId); 
      Log.i(TAG, "Selected: " + item.description); 
      PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi 
        .getPlaceById(mGoogleApiClient, placeId); 
      placeResult.setResultCallback(mUpdatePlaceDetailsCallback); 
      Log.i(TAG, "Fetching details for ID: " + item.placeId); 
     } 
    }; 

    @Override 
    public void onDestroyView() { 
     super.onDestroyView(); 
     if(mGoogleApiClient != null && mGoogleApiClient.isConnected()) { 
      mGoogleApiClient.stopAutoManage(getActivity()); 
      mGoogleApiClient.disconnect(); 
     } 
    } 

    private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback 
      = new ResultCallback<PlaceBuffer>() { 
     @Override 
     public void onResult(PlaceBuffer places) { 
      if (!places.getStatus().isSuccess()) { 
       Log.e(TAG, "Place query did not complete. Error: " + 
         places.getStatus().toString()); 
       return; 
      } 
      // Selecting the first object buffer. 
     } 
    }; 
} 

그리고 여기에 어댑터 코드 :

class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> { 

private static final String TAG = "RecyclerViewAdapter"; 

private Context context; 
private List<RunData> dataList = new ArrayList<>(); 
private LayoutInflater inflater; 
private RunDbHelper runDbHelper; 

RecyclerViewAdapter(Context context, List<RunData> dataList1) { 

    this.context = context; 
    this.dataList = dataList1; 
    this.runDbHelper = RunDbHelper.getInstance(this.context); 
    inflater = LayoutInflater.from(context); 
} 

@Override 
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View inflateView = inflater.inflate(R.layout.fragment_recycler_row, parent, false); 
    return new RecyclerViewHolder(inflateView); 
} 

@Override 
public void onBindViewHolder(final RecyclerViewHolder holder, final int position) { 

    holder.runID.setText(dataList.get(position).run_id); 
    holder.collectAddress.setText(dataList.get(position).collect_address); 
    holder.deliveryAddress.setText(dataList.get(position).delivery_address);  

    holder.ivEdit.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) {    
      RunData runData = new RunData(); 
      runData.run_id = holder.runID.getText().toString();     
      runData.collect_address = holder.collectAddress.getText().toString(); 
      runData.delivery_address = holder.deliveryAddress.getText().toString();     
      dialogEditRun(runData, position); 
     } 
    }); 
} 

@Override 
public int getItemCount() { 
    return dataList.size(); 
} 

public void dialogEditRun(RunData runData, int position) { 

    // Get the Activity for layout inflater as this dialog runs inside a fragment 
    LayoutInflater inflater = LayoutInflater.from(context); 
    final View inflaterView = inflater.inflate(R.layout.dialog_edit_run, null); 
    // Data entry field objects 
    final String mRunID; 

    final AutoCompleteTextView collectAddressACTV = (AutoCompleteTextView) inflaterView.findViewById(R.id.actv_edit_collect_address); 
    final AutoCompleteTextView deliveryAddressACTV = (AutoCompleteTextView) inflaterView.findViewById(R.id.actv_edit_delivery_address); 

    mRunID = runData.run_id; 
    collectAddressACTV.setText(runData.collect_address); 
    deliveryAddressACTV.setText(runData.delivery_address); 

    // HERE THE FIELDS AND THE SUGGESTIONS ARE LINKED 
    // Set directions into recyclerViewAdapter for autocomplete 
    // here is still using G. Places WebService API. Should be G. Places API for Android, using GoogleApiClient 
    collectAddressACTV.setAdapter(new GooglePlacesAutocompleteAdapter(context, R.layout.dialog_new_run_autocomplete)); 
    deliveryAddressACTV.setAdapter(new GooglePlacesAutocompleteAdapter(context, R.layout.dialog_new_run_autocomplete)); 

    // Dialog Builder 
    AlertDialog.Builder editRunDialog = new AlertDialog.Builder(context); 
    editRunDialog.setTitle(R.string.dialog_update_run_title).setView(inflaterView); 

    editRunDialog.setPositiveButton(R.string.button_positive, new DialogInterface.OnClickListener() { 

     @Override 
     public void onClick(DialogInterface dialog, int id) { 

      RunData runData = new RunData(); 

      int position = (int) run_date.getTag(); 
      runData.run_id = mRunID; 
      runData.collect_address = getStringOrEmpty(collectAddressACTV); 
      runData.delivery_address = getStringOrEmpty(deliveryAddressACTV); 

      if (!(runData.collect_address.isEmpty() && runData.delivery_address.isEmpty())){ 
       // try to update, if success update recycler. 
       if (runDbHelper.updateRun(runData, context)){ 
        // atualiza o recyclerview 
        dataList.remove(position); 
        notifyItemRemoved(position); 
        dataList.add(position,runData); 
        notifyItemRangeChanged(position, dataList.size()); 
        notifyItemInserted(position); 

       } else { 
        Toast.makeText(context, "No record updated", Toast.LENGTH_SHORT).show(); 
       } 
      } else { 
       Toast.makeText(context, "Inform at least one direction", Toast.LENGTH_SHORT).show(); 
      } 
     } 

    }); 

    editRunDialog.setNegativeButton(R.string.button_negative, new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int whichButton) { 
      dialog.cancel(); 
     } 
    }); 

    editRunDialog.create(); 
    editRunDialog.show(); 
} 

private String getStringOrEmpty(EditText editText) { 
    String mString = editText.getText().toString(); 
    mString = (mString.isEmpty() ? "" : mString); 
    return mString; 
} 

class RecyclerViewHolder extends RecyclerView.ViewHolder { 
    TextView runID, collectAddress, deliveryAddress; 
    ImageView ivEdit; 

    RecyclerViewHolder(View rowView) { 
     super(rowView); 
     runID = (TextView) rowView.findViewById(R.id.runId); 
     collectAddress = (TextView) rowView.findViewById(R.id.collectAddress); 
     deliveryAddress = (TextView) rowView.findViewById(R.id.deliveryAddress); 
     ivEdit = (ImageView) rowView.findViewById(R.id.ivEdit); 
    } 
} 
} 

내가 에서의 reclycler 어댑터 내부의 GoogleApiClient를 인스턴스화하는 코드를 추가하려고

onCreateViewHolder (ViewGroup parent, int viewType), 안드로이드 스튜디오 못하게 해줘. 내가 enableAutoManage 요약

  mGoogleApiClient = new GoogleApiClient.Builder(context) 
        .addApi(Places.GEO_DATA_API) 
        .enableAutoManage(HEREISTHEERROR, GOOGLE_API_CLIENT_ID, this) // nada do que tentei colocar aqui no lugar do XXXXXXX funcionou! 
        .addConnectionCallbacks(this) 
        .build(); 

에 적합한 참조를 찾을 수없는, 내가 무엇을 달성하고자하는 것은에 AlertDialog 내부에 표시되는 형태로 추가 제안이나 편집 방향 데이터를 수신하는 것입니다.

Android 용 Google Places API를 사용해야합니다 (GoogleApiClient).

올바른 접근 방식인지 확실하지 않으므로 제안이나 해결 방법을 환영합니다.

답변

0

나는이 질문을 해결했다.

GoogleApiClient에는 enableAutoManage() 만 사용할 수 있습니다. API에 대한 다른 호출은 생명주기를 처리해야합니다.

Accessing Google APIs