Infowindow中的自定义滑块无法获得焦点 - Android Google Map v2

时间:2014-07-31 07:48:12

标签: android google-maps android-maps-v2

我正在尝试在信息窗口创建设置面板,以便我们可以使用信息窗口内的滑块来调整某些内容。在实现和执行方面,我发现信息窗口总是获得onclick焦点。单击信息窗口内的滑块,没有任何响应。 Woudl,请告诉我如何在用户点击并拖动信息窗口时使滑块控件聚焦 ?

以下是我的代码:

package com.larry.proto.maptest;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader.TileMode;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.os.Vibrator;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
public class MainActivity extends FragmentActivity  implements LocationListener {


    final int RQS_GooglePlayServices = 1;

    private GoogleMap myMap;
    Location myLocation;
    LocationManager lm;
    private ArrayList<Checkpoint> cpList = new ArrayList<Checkpoint> ();
    private ArrayList<Marker> thisMarkerList = new ArrayList<Marker> ();
    private List<LatLng> ppoints = new ArrayList<LatLng> ();
    private int requestCode;
    private  LatLng globalPoint;
    private String infoDesp;
    private String infoLat;
    private String infoLong;
    private Marker mSelectedMarker;
    private boolean mRefreshingInfoWindow;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        SupportMapFragment sFragment =  (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        myMap =  sFragment.getMap();
        myMap.setMyLocationEnabled(true);
        myMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        lm = (LocationManager) getSystemService (LOCATION_SERVICE);
        String provider = lm.getBestProvider(new Criteria(), true);
        Location loc = lm.getLastKnownLocation(provider);
        if(loc!=null)
        {
            onLocationChanged(loc);
        }
        SharedPreferences prefs = getApplicationContext().getSharedPreferences("MyPref", 0);
        String restoredLat = prefs.getString("lat", null);
        String restoredLng = prefs.getString("lng", null);
        String restoredText = prefs.getString("title", null);

        myMap.setOnMapLongClickListener(setting());
        myMap.getUiSettings().setRotateGesturesEnabled(false);


        if(null!=restoredText){
            double lat = null!=restoredLat ? Double.parseDouble(restoredLat) : null;
            double lng = null!=  restoredLng ? Double.parseDouble(restoredLng) : null;
            LatLng posi = new LatLng(lat, lng);
            myMap.addMarker(new MarkerOptions().position(posi).title(restoredText) 
                    .snippet(String.valueOf(restoredLat) + "," + 
                            String.valueOf(restoredLng))
                            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)));
            CameraPosition cameraPosition = new CameraPosition.Builder().target(posi).zoom(14).build(); 
            myMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
        }
    }

    private OnMapLongClickListener setting() {
        // TODO Auto-generated method stub
        return new OnMapLongClickListener(){

            @Override
            public void onMapLongClick(LatLng point) {
                // TODO Auto-generated method stub
                globalPoint = point;
                requestCode = 0;
                Intent mIntent = new Intent();  
                mIntent.setClass(MainActivity.this,  SliderActivity.class);  
                startActivityForResult(mIntent, requestCode);  
            }};
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onResume() {

        super.onResume();
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());

        if (resultCode == ConnectionResult.SUCCESS) {
            Toast.makeText(getApplicationContext(),
                    "isGooglePlayServicesAvailable SUCCESS", Toast.LENGTH_LONG)
                    .show();
        } else {
            GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                    RQS_GooglePlayServices);
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        // TODO Auto-generated method stub
        LatLng latlng = new LatLng(location.getLatitude() , location.getLongitude());
        myMap.moveCamera(CameraUpdateFactory.newLatLng(latlng));
        myMap.animateCamera(CameraUpdateFactory.zoomTo(11));
    }


    private void addMarkersToMap() {
        myMap.clear();

        ppoints.clear();

        LatLng ll; 
        for (int i = 0; i < cpList.size(); i++) {         
            ll = new LatLng(cpList.get(i).getPoint().latitude, cpList.get(i).getPoint().longitude);
            ppoints.add(ll);
        }
        int length  = ppoints.size();
        LatLng first = null ;
        if(length >2){
            for( int i = 0 ; i < ppoints.size() -1  ; i++){
                first = ppoints.get(0);
                LatLng pt = ppoints.get(i);
                LatLng ptNext = ppoints.get(i+1);
                DrawArrowHead(myMap, pt, ptNext , Color.RED  , cpList.get(i).getDesp() , i+1 , true);
                createDashedLine(myMap, pt, ptNext , Color.RED);
            }
            List<LatLng> current =  ppoints.subList(ppoints.size()-2, ppoints.size());
            for( int i = 0 ; i < current.size() -1  ; i++){
                first = ppoints.get(0);
                LatLng pt = current.get(i);
                LatLng ptNext = current.get(i+1);
                DrawArrowHead(myMap, pt, ptNext , Color.BLUE , cpList.get(i).getDesp() ,i+1 , false);
                createDashedLine(myMap, pt, ptNext , Color.BLUE);
            }

            myMap.addMarker(new MarkerOptions().position(new LatLng(first.latitude ,
                    first.longitude )).title("Starting Point") 
                    .snippet(String.valueOf(first.latitude) + "," + 
                            String.valueOf(first.longitude))
                            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
        }else if( length ==1){
            for( int i = 0 ; i < ppoints.size() ; i++){
                myMap.addMarker(new MarkerOptions().position(new LatLng(ppoints.get(i).latitude ,
                        ppoints.get(i).longitude )).title("Starting Point") 
                        .snippet(String.valueOf(ppoints.get(i).latitude) + "," + 
                                String.valueOf(ppoints.get(i).longitude))
                                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
            }
        }

        else{



            myMap.addPolyline(new PolylineOptions().width(5).color(Color.BLUE).addAll(ppoints));

            for( int i = 0 ; i < ppoints.size() -1  ; i++){
                first = ppoints.get(0);
                LatLng pt = ppoints.get(i);
                LatLng ptNext = ppoints.get(i+1);
                DrawArrowHead(myMap, pt, ptNext , Color.BLUE , cpList.get(i).getDesp() , i+1  , true);
                createDashedLine(myMap, pt, ptNext , Color.BLUE);
            }

            myMap.addMarker(new MarkerOptions().position(new LatLng(first.latitude ,
                    first.longitude )).title("Starting Point") 
                    .snippet(String.valueOf(first.latitude) + "," + 
                            String.valueOf(first.longitude))
                            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
        }

    }

    private final double degreesPerRadian = 180.0 / Math.PI;


    private void DrawArrowHead(GoogleMap mMap, LatLng from, LatLng to , int color, String desp , int number , boolean boolR){
        double bearing = GetBearing(from, to);
        double adjBearing = Math.round(bearing / 3) * 3;
        while (adjBearing >= 120) {
            adjBearing -= 120;
        }
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy); 
        URL url;
        Bitmap image = null;
        try {
            String name = "dir_" + String.valueOf((int)adjBearing) + ".png";
            String link = "http://www.google.com/intl/en_ALL/mapfiles/" + name;
            Log.d("ling k" , link);
            url = new URL(link);
            try {
                String imageName = link.substring(link.lastIndexOf("/"), link.length()); 
                File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator +  imageName ); 
                if(!file.exists()){ 
                    startService(new Intent(MainActivity.this , ImageIntentService.class).putExtra("urlpath", link));
                    Options  mBitmapOptions = new BitmapFactory.Options();
                    mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_4444;
                    mBitmapOptions.inDither = true;
                    mBitmapOptions.inPurgeable = true;
                    mBitmapOptions.inInputShareable = true;
                    Rect rec = new Rect();
                    rec.set(-1, -1, -1, -1);
                    image = BitmapFactory.decodeStream(url.openConnection().getInputStream() , rec  , mBitmapOptions);
                    image = getResizedBitmap(image ,  image.getHeight()*2 , image.getWidth()*2);
                }else{
                    Options  mBitmapOptions = new BitmapFactory.Options();
                    mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_4444;
                    mBitmapOptions.inDither = true;
                    mBitmapOptions.inPurgeable = true;
                    mBitmapOptions.inInputShareable = true;
                    Rect rec = new Rect();
                    rec.set(-1, -1, -1, -1);
                    try {
                        image = BitmapFactory.decodeStream(new FileInputStream(file), null, mBitmapOptions);
                        image = getResizedBitmap(image ,  image.getHeight()*2 , image.getWidth()*2);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }

                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (image != null){
            float anchorX = 0.5f;
            float anchorY = 0.5f;

            int offsetX = 0;
            int offsetY = 0;
            int width = image.getWidth();
            int height = image.getHeight();
            if (bearing >= 292.5 && bearing < 335.5){
                offsetX = 24;
                offsetY = 24;
                offsetX = width;
                offsetY = height;
            }
            else if (bearing >= 247.5 && bearing < 292.5){
                offsetX = 24;
                offsetY = 12;
                offsetX = width;
                offsetY = height/2;
            }
            else if (bearing >= 202.5 && bearing < 247.5){
                offsetX = 24;
                offsetY = 0;
                offsetX = width;
                offsetY = 0;
            }
            else if (bearing >= 157.5 && bearing < 202.5){
                offsetX = 12;
                offsetY = 0;
                offsetX = width/2;
                offsetY = 0;
            }
            else if (bearing >= 112.5 && bearing < 157.5){
                offsetX = 0;
                offsetY = 0;
            }
            else if (bearing >= 67.5 && bearing < 112.5){
                offsetX = 0;
                offsetY = 12;
                offsetX = 0;
                offsetY = height/2;
            }
            else if (bearing >= 22.5 && bearing < 67.5){
                offsetX = 0;
                offsetY = 24;
                offsetX = 0;
                offsetY = height;
            }
            else {
                offsetX = 12;
                offsetY = 24;
                offsetX = width/2;
                offsetY = height;
            }
            Bitmap wideBmp;
            Canvas wideBmpCanvas;
            Rect src, dest;

            wideBmp = Bitmap.createBitmap(image.getWidth() *2, image.getHeight() * 2, image.getConfig());
            wideBmpCanvas = new Canvas(wideBmp); 

            src = new Rect(0, 0, image.getWidth(), image.getHeight());
            dest = new Rect(src); 
            dest.offset(offsetX, offsetY); 
            Paint maskedPaint = new Paint();
            int r =  Color.red(color);
            int g =  Color.green(color);
            int b =  Color.blue(color);


            ColorMatrix cm = new ColorMatrix();
            cm.set(new float[] {
                    1, 0, 0, 0, r,
                    0, 1, 0, 0, g,
                    0, 0, 1, 0, b,
                    0, 0, 0, 1, 0 }); // last line is antialias
            maskedPaint.setColorFilter(new ColorMatrixColorFilter(cm));
            maskedPaint.setShader(new BitmapShader(image, TileMode.REPEAT, TileMode.REPEAT));

            // color
            wideBmpCanvas.drawBitmap(image, src, dest, maskedPaint);

            if(boolR == true){
                Paint stroke = new Paint();
                stroke.setColor(Color.YELLOW);
                stroke.setAntiAlias(false);
                stroke.setStrokeWidth(8);
                stroke.setTextSize(60);
                wideBmpCanvas.drawText(String.valueOf(number), 
                        (float)wideBmpCanvas.getWidth()/2, (float)wideBmpCanvas.getHeight()/2, stroke);
            }
            infoDesp = desp;
            infoLat =String.valueOf(to.latitude);
            infoLong = String.valueOf(to.longitude);

             mMap.setInfoWindowAdapter(new CustomInfoAdapter());
             mMap.addMarker(new MarkerOptions()
            .position(to).title(desp)
            .snippet(String.valueOf(to.latitude) + "," + String.valueOf(to.longitude))
            .icon(BitmapDescriptorFactory.fromBitmap(wideBmp))
            .anchor(anchorX, anchorY));    
        }
    }

    class CustomInfoAdapter implements InfoWindowAdapter{

        @Override
        public View getInfoContents(Marker arg0) {

            View marker = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).
                    inflate(R.layout.custom_marker_layout, null);

            if (!mRefreshingInfoWindow) {
                mSelectedMarker = arg0;

                TextView numTxt = (TextView) marker.findViewById(R.id.num_txt);
                TextView lat1 = (TextView) marker.findViewById(R.id.textView1);
                TextView long1 = (TextView) marker.findViewById(R.id.textView2);
                SeekBar sk  = (SeekBar) marker.findViewById(R.id.seekBar1);
                numTxt.setText(arg0.getTitle());
                lat1.setText(String.valueOf(arg0.getPosition().latitude));
                long1.setText(String.valueOf(arg0.getPosition().longitude));
                sk.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {       
                    @Override       
                    public void onStopTrackingTouch(SeekBar seekBar) {

                    }       
                    @Override       
                    public void onStartTrackingTouch(SeekBar seekBar) {     
                    }       
                    @Override       
                    public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
                        if(progress==25){
                            Vibrator v = (Vibrator) MainActivity.this.getSystemService(Context.VIBRATOR_SERVICE);
                            v.vibrate(500);
                        }
                    }
                });
                sk.requestFocus();

            }else{
                refreshInfoWindow();
            }
            return marker;
        }

        @Override
        public View getInfoWindow(Marker arg0) {
            return null;
        }

        private void refreshInfoWindow() {
            if (mSelectedMarker == null) {
                return;
            }
            mRefreshingInfoWindow = true;
            mSelectedMarker.showInfoWindow();
            mRefreshingInfoWindow = false;
        }
    }


    private double GetBearing(LatLng from, LatLng to){
        double lat1 = from.latitude * Math.PI / 180.0;
        double lon1 = from.longitude * Math.PI / 180.0;
        double lat2 = to.latitude * Math.PI / 180.0;
        double lon2 = to.longitude * Math.PI / 180.0;

        double angle = - Math.atan2( Math.sin( lon1 - lon2 ) * Math.cos( lat2 ), 
                Math.cos( lat1 ) * Math.sin( lat2 ) - Math.sin( lat1 ) * Math.cos( lat2 ) * Math.cos( lon1 - lon2 ) );

        if (angle < 0.0)
            angle += Math.PI * 2.0;

        angle = angle * degreesPerRadian;

        return angle;
    }

    public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
        return resizedBitmap;
    }

    public void writeToFile(Checkpoint cp , String vertical , String circle ,  File f){
        OutputStreamWriter outStreamWriter = null;
        FileOutputStream outStream = null;
        try {

            outStream = new FileOutputStream(f, true);
            outStreamWriter = new OutputStreamWriter(outStream); 
            outStreamWriter.write(new char[]{});
            outStreamWriter.append(cp.getDesp());
            outStreamWriter.append('\n');
            outStreamWriter.append(String.valueOf(cp.getPoint().latitude));
            outStreamWriter.append('\n');
            outStreamWriter.append(String.valueOf(cp.getPoint().longitude));
            outStreamWriter.append('\n');
            outStreamWriter.append("the vertical slider value is :" + vertical);
            outStreamWriter.append('\n');
            outStreamWriter.append("the circle slider value is :" + circle);
            outStreamWriter.append('\n');

            outStreamWriter.flush();
            outStreamWriter.close();

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


    public static void createDashedLine(GoogleMap map, LatLng latLngOrig, LatLng latLngDest, int color){
        double difLat = latLngDest.latitude - latLngOrig.latitude;
        double difLng = latLngDest.longitude - latLngOrig.longitude;

        double zoom = map.getCameraPosition().zoom;

        double divLat = difLat / (zoom * 2);
        double divLng = difLng / (zoom * 2);

        LatLng tmpLatOri = latLngOrig;

        for(int i = 0; i < (zoom * 2); i++){
            LatLng loopLatLng = tmpLatOri;

            if(i > 0){
                loopLatLng = new LatLng(tmpLatOri.latitude + (divLat * 0.25f), tmpLatOri.longitude + (divLng * 0.25f));
            }

            Polyline polyline = map.addPolyline(new PolylineOptions()
            .add(loopLatLng).add(new LatLng(tmpLatOri.latitude + divLat, tmpLatOri.longitude + divLng))
            .color(color).width(5f));
            tmpLatOri = new LatLng(tmpLatOri.latitude + divLat, tmpLatOri.longitude + divLng);
        }
    }

    @Override  
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  


        super.onActivityResult(requestCode, resultCode, data);  
        if(requestCode  ==0){
            if(resultCode ==RESULT_OK){
                String change01 = data.getStringExtra("change01");  
                String change02 = data.getStringExtra("change02");  

                Toast.makeText(MainActivity.this  , change01 + " " + change02 , Toast.LENGTH_SHORT).show();
                Checkpoint cp = new Checkpoint("Destination", globalPoint, 0);
                Log.d("lati long" , String.valueOf(globalPoint.latitude) + ":" +  String.valueOf(globalPoint.longitude));
                cpList.add(cp);

                File dir = new File( Environment.getExternalStorageDirectory().getAbsolutePath() + 
                        File.separator + "NOVAX" );
                if(!dir.exists()){
                    dir.mkdirs();
                }


                Checkpoint lastlyAdded = cpList.get(cpList.size() -1 );
                writeToFile(lastlyAdded ,  change01 , change02 ,    new File(dir.getAbsolutePath()+ File.separator +  "text.txt" ));

                SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
                SharedPreferences.Editor editor = pref.edit();
                editor.clear();
                editor.putString("title", lastlyAdded.getDesp());
                editor.putString("lat", String.valueOf(lastlyAdded.getPoint().latitude));
                editor.putString("lng",  String.valueOf(lastlyAdded.getPoint().longitude));
                editor.commit();

                for(int i = 0 ; i < cpList.size() ; i ++){
                    Checkpoint cPoint =  cpList.get(i);
                    if(!cPoint.getPoint().equals(lastlyAdded.getPoint())){
                        cPoint.setState(1); 
                        cPoint.setDesp("Checkpoint "+String.valueOf(i+1) );
                    }
                }
                addMarkersToMap();
            }
        }
    }  
}

1 个答案:

答案 0 :(得分:0)

根据Google的文档,自定义信息窗口不是真正的窗口,而是插入到地图视图中的渲染图像。谷歌地图中唯一可以获得焦点的项目似乎就是标记本身。信息窗口采用onClickListener。这是相关信息。请查看其文档中Custom Info Windows部分中的注释。

  

注意:绘制的信息窗口不是实时视图。视图在返回时呈现为图像(使用View.draw(Canvas))。这意味着对视图的任何后续更改都不会被地图上的信息窗口反映出来。要稍后更新信息窗口(例如,在加载图像后),请调用showInfoWindow()。此外,信息窗口将不会考虑正常视图(例如触摸或手势事件)的任何典型交互。但是,您可以在整个信息窗口中收听通用点击事件,如以下部分所述。

可能有一种方法可以使用FrameLayout和一个视图覆盖,就像一个自定义信息窗口,但这更像是一个黑客而不是支持的解决方案。