lundi 25 septembre 2017

Refresh the activity based on checkbox's dynamically varying input

I have created an application which highlights the US states based on the population density. I want to highlight only the states which user needs to see. This is done using RecyclerView and checkbox.

This is my .xml file of MainActivity.

<FrameLayout
    xmlns:android="http://ift.tt/nIICcg"
    xmlns:app="http://ift.tt/GEGVYd"
    xmlns:mapbox="http://ift.tt/GEGVYd"
    xmlns:tools="http://ift.tt/LrGmb4"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.aadhilahmed.choroplethmapbox1.MainActivity">


    <com.mapbox.mapboxsdk.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        mapbox:mapbox_cameraTargetLat="37.996162943943155"
        mapbox:mapbox_cameraTargetLng="-101.0299301147461"
        mapbox:mapbox_cameraTilt="20"
        mapbox:mapbox_cameraZoom="2"
        mapbox:mapbox_styleUrl="mapbox://styles/aadhilahmed/cj7ps8l3a8uxs2rocjqnakcrs"/>

    <android.support.v7.widget.RecyclerView
        android:layout_width="150dp"
        android:layout_height="250dp"
        android:id="@+id/recyclerView"
        android:paddingRight="5dp"
        android:paddingBottom="8dp"
        android:background="#ffffff"
        android:layout_gravity="bottom|right">

    </android.support.v7.widget.RecyclerView>
</FrameLayout>

This is my MainActivity.

public class MainActivity extends AppCompatActivity {

private MapView mapView;
String jsonData;
JSONObject jsonObject;
JSONArray jsonArray;
List<List<LatLng>> coordinates=new ArrayList<>();
List<String> colours=new ArrayList<>();
List<String> adapterLegend= Arrays.asList("0-10","10-20","20-50","50-100","100-200","200-500","500-1000","1000-10000");
int[] images={R.drawable.colormap1,
              R.drawable.colormap2,
              R.drawable.colormap3,
              R.drawable.colormap4,
              R.drawable.colormap5,
              R.drawable.colormap6,
              R.drawable.colormap7,
              R.drawable.colormap8
};
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private List<ListItem> listItemss;
private List<ListItem> currentCheckedItems=new ArrayList<>();
int[] selectedRangeArray=new int[50];

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

    Mapbox.getInstance(this,"pk.eyJ1IjoiYWFkaGlsYWhtZWQiLCJhIjoiY2o2MXNzY3I5MHoyajMybW9raTI1emJmbiJ9.paxtpoOPEQDuVN19tlfpVw");
    setContentView(R.layout.activity_main);

    mapView=(MapView)findViewById(R.id.mapView);
    mapView.onCreate(savedInstanceState);

    recyclerView=(RecyclerView)findViewById(R.id.recyclerView);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));

    listItemss=new ArrayList<>();
    for(int i=0;i<8;i++){
        ListItem listItem=new ListItem(images[i],adapterLegend.get(i));
        listItemss.add(listItem);
    }

    adapter=new MyAdapter(listItemss,this, new MyAdapter.OnItemCheckListener() {
        @Override
        public void onItemCheck(ListItem item) {
            currentCheckedItems.add(item);
        }

        @Override
        public void onItemUncheck(ListItem item) {
            currentCheckedItems.remove(item);
        }
    });
    recyclerView.setAdapter(adapter);

    RangeOfCheckedItems range=new RangeOfCheckedItems();
    selectedRangeArray=range.limitFinder(currentCheckedItems.size(),currentCheckedItems);


    try
    {
        jsonData= convertJSONFile("stateData.geojson",MainActivity.this);
        jsonObject=new JSONObject(jsonData);
        jsonArray=jsonObject.getJSONArray("features");
        choroplethManipulation();

    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    }



}

public void drawMap(final List<List<LatLng>> points, final List<String> colur){
    mapView.getMapAsync(new OnMapReadyCallback() {
        @Override
        public void onMapReady(MapboxMap mapboxMap) {
            for(int m=0;m< colours.size();m++) {
                mapboxMap.addPolygon(new PolygonOptions()
                        .addAll(points.get(m))
                        .fillColor(Color.parseColor(colur.get(m)))
                );
            }
        }
    });
}

public void choroplethManipulation() throws JSONException {
    for(int state=0;state<jsonArray.length();state++) {
        boolean checked = false;

        //Choose color for the area
        float orders = (float) jsonArray.getJSONObject(state).getJSONObject("properties").getDouble("density");
        for (int n = 0; n < currentCheckedItems.size(); n++) {
            if ((int) orders > selectedRangeArray[n] && (int) orders < selectedRangeArray[n + 1])
                checked = true;
        }

        if (checked == true) {
            //Collecting coordinates for drawing polygon
            JSONObject geometry = jsonArray.getJSONObject(state).getJSONObject("geometry");
            String type = geometry.getString("type");

            if (type.equals("Polygon")) {
                JSONArray points = geometry.getJSONArray("coordinates").getJSONArray(0);
                List<LatLng> polygonpoints = new ArrayList<>();
                for (int i = 0; i < points.length(); i++) {
                    polygonpoints.add(new LatLng(points.getJSONArray(i).getDouble(1), points.getJSONArray(i).getDouble(0)));
                }
                coordinates.add(polygonpoints);
                colours.add(ColorSelector.ColorChooser.chooseColor(orders));
            } else {
                JSONArray points = geometry.getJSONArray("coordinates");
                for (int p = 0; p < points.length(); p++) {
                    JSONArray splits = points.getJSONArray(p).getJSONArray(0);
                    List<LatLng> polygonpoints = new ArrayList<>();
                    for (int x = 0; x < splits.length(); x++) {
                        polygonpoints.add(new LatLng(splits.getJSONArray(x).getDouble(1), splits.getJSONArray(x).getDouble(0)));
                    }
                    coordinates.add(polygonpoints);
                    colours.add(ColorSelector.ColorChooser.chooseColor(orders));
                }
            }
        }
    }

    drawMap(coordinates,colours);
}


public String convertJSONFile(String filename, Context context) throws IOException {
    AssetManager manager=context.getAssets();
    InputStream file=manager.open(filename);
    byte[] formArray=new byte[file.available()];
    file.read(formArray);
    file.close();

    return new String(formArray);
}

}

And this is a small class which gives the upper and lower limits of checked checkboxes.

public class RangeOfCheckedItems {

int limits[]=new int[50];

public int[] limitFinder(int num,List<ListItem> checkedItems){

    for(int i=0;i<num;i++){
        String s=checkedItems.get(i).getRange();
        StringTokenizer st=new StringTokenizer(s,"-");
        limits[i]=Integer.parseInt(st.nextToken());
        limits[i+1]=Integer.parseInt(st.nextToken());
    }
    return limits;
}
}

This is my Adapterclass.

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    interface OnItemCheckListener{
      void onItemCheck(ListItem item);
        void onItemUncheck(ListItem item);
    };

    private List<ListItem> listItems;
    private Context context;
    @NonNull
    private OnItemCheckListener onItemCheckListener;

    public MyAdapter(List<ListItem> listItems,Context context,@NonNull OnItemCheckListener onItemCheckListener){
        this.listItems=listItems;
        this.context=context;
        this.onItemCheckListener=onItemCheckListener;

    }


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v= LayoutInflater.from(parent.getContext())
                .inflate(R.layout.legend_adapter,parent,false);
        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
            ListItem listItem=listItems.get(position);
            holder.image.setImageResource(listItem.getImage());
            holder.rangeinfo.setText(listItem.getRange());

            if(holder instanceof ViewHolder){
                final ListItem currentItem=listItems.get(position);

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

                    @Override
                    public void onClick(View v) {
                        ((ViewHolder)holder).checkBox.setChecked(!((ViewHolder)holder).checkBox.isChecked());
                        if(((ViewHolder)holder).checkBox.isChecked()){
                            onItemCheckListener.onItemCheck(currentItem);
                        }else {
                            onItemCheckListener.onItemUncheck(currentItem);
                        }
                    }
                });
            }
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder{

        public ImageView image;
        public TextView rangeinfo;
        public CheckBox checkBox;

        public ViewHolder(View itemView) {
            super(itemView);

            image=(ImageView)itemView.findViewById(R.id.colorLegend);
            rangeinfo=(TextView)itemView.findViewById(R.id.textLegend);
            checkBox=(CheckBox)itemView.findViewById(R.id.checkboxLegend);
            checkBox.setClickable(false);
        }

        public void setOnClickListener(View.OnClickListener onClickListener){
            itemView.setOnClickListener(onClickListener);
        }

    }
}

My problem is I want to call choroplethManipulation() method only after I get inputs from checkbox. But after all the execution only, my Activity is inflating, hence I am unable to give my inputs and checked variable always remains false. Once I check the boxes, I need my Activity to dynamically react and show only selected results. How can this be done?




Aucun commentaire:

Enregistrer un commentaire