2017年8月26日 星期六

來點名囉-點名程式android版本發佈試用

下跤是點名程式的原始碼,歡迎有趣味的人掠轉去研究。自由軟體上大精神是開放,完全無藏起來的想法。若干焦試用這个android apk,揤這个連結




package tw.cyc.grid4;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentTransaction;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.NumberPicker;
import android.widget.RadioGroup;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutionException;

public class MainActivity extends Activity implements NumberPicker.OnValueChangeListener {

    ArrayList<HashMap<String, Integer>> location = new ArrayList<HashMap<String, Integer>>();

    public int col = 4;
    public int pos = 0;
    public int num = 0;
    public int selected = 0;
    public int fontSize = 32;

    final int[] color = {Color.argb(255, 153, 51, 0), Color.argb(255, 153, 206, 255), Color.argb(255, 255, 153, 0), Color.argb(255, 194, 194, 214)};
    long startTime = 0;
    long lastClickTime = 0;
    final int CLICK_PERIOD = 400;
    GridView grid;
    static GridAdapter adapter;
    static SharedPreferences spref = null;
    static RadioGroup column;
    static EditText number ;
    static Spinner spinner;
    static RadioGroup direction;
    static String pack = "";
    static public boolean changed = false;
    private final static String MY_MESSAGE = "tw.cyc.sendmessage";
    int monitorWidth = 0;
    int monitorHeight = 0;

    public class GridAdapter extends SimpleAdapter {
        Context context = null;

        public GridAdapter(Context context, List<? extends Map<String, ?>> numbers,
                           int resource, String[] from, int[] to) {
            super(context, numbers, resource, from, to);
            this.context = context;
            monitorWidth = getResources().getDisplayMetrics().widthPixels;
            monitorHeight = getResources().getDisplayMetrics().heightPixels;
        }

        @Override        public View getView(int position, View convertView, ViewGroup parent) {
            convertView = LayoutInflater.from(context).inflate(R.layout.gridview_item, null);
            HashMap<String, Integer> theMap = (HashMap<String, Integer>) getItem(position);
            TextView main_text = (TextView) convertView.findViewById(R.id.main_text);
            TextView second_text = (TextView) convertView.findViewById(R.id.second_text);

            if (theMap.get("note") < 0) {  //note less 0 is virtual                main_text.setText("");
            }
            else if (theMap.get("note") > 0 && theMap.get("note") < 10) {
                main_text.setText("0".concat(theMap.get("note").toString()));
            }
            else {
                main_text.setText(theMap.get("note").toString());
            }
            main_text.setTextSize(fontSize);
            main_text.setTextColor(color[pos]);
            int rowHeight = 0;
            if (location.size()/col <= 10) {
                rowHeight = monitorHeight / ((location.size()/col + 4));
            }
            else rowHeight = monitorHeight / 14;
            ListView.LayoutParams param = new ListView.LayoutParams((int) ((monitorWidth - 100) / col), rowHeight);
            convertView.setLayoutParams(param);

            if (theMap.get("second") < 0) {
                second_text.setText("");
            }
            else if (theMap.get("second") == 0) {
                second_text.setText("");
            }
            else {
                main_text.setTextColor(Color.argb(255, 0, 153, 0));
                second_text.setText(" ".concat(theMap.get("second").toString()));
                second_text.setTextColor(Color.argb(255, 218, 179, 255));
                second_text.setTextSize(fontSize - 8);
            }

            return convertView;
        }

    }

    public int getVirtualNumber(ArrayList<HashMap<String, Integer>> location) {
        int virtualNumber = 0;
        for (int j=0; j<location.size(); j++) {
            if (location.get(j).get("second") < 0) {
                virtualNumber++ ;
            }
        }
        return virtualNumber;
    }

    public int randomSelect(View v) {    //no need to check transpose
        startTime = System.currentTimeMillis();
        if (startTime - lastClickTime < CLICK_PERIOD && lastClickView == v) {
            int realSize = location.size() - getVirtualNumber(location);
            if (realSize - selected == 0) {
                Toast.makeText(MainActivity.this, " 無免點囉!", Toast.LENGTH_SHORT).show();
                return 0;
            }
            int random = (new Random()).nextInt(realSize - selected);
            int count = 0;  //0 is most low value            for (int j=0; j<location.size(); j++) {
                if (location.get(j).get("second") == 0) {
                    if (count == random) {
                        selected = selected + 1;
                        location.get(j).put("second", Integer.valueOf(selected));
                        AlertDialog.Builder builder = new AlertDialog.Builder(this);
                        TextView msg = new TextView(this); msg.setTextSize(50);
                        msg.setTextColor(Color.RED);msg.setHeight(400);
                        msg.setText(location.get(j).get("note").toString());
                        msg.setGravity(Gravity.CENTER);
                        builder.setView(msg);
                        AlertDialog dialog = builder.create();
                        dialog.show();

                        WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
                        params.width = monitorWidth / 3;
                        dialog.getWindow().setAttributes(params);

                        break;
                    }
                    else count++;
                }
            }
            adapter.notifyDataSetChanged();
            return random;
        }
        lastClickTime = startTime;
        lastClickView = v;
        return 0;
    }

   public int getTrow() {
       return ((int) (location.size()/col)) + 1;
   }

    @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) { // 攔截返回鍵            AlertDialog adialog = new AlertDialog.Builder(this)
                    .setTitle("欲走矣嗎?")
                    .setPositiveButton("確定",
                            new DialogInterface.OnClickListener() {
                                @Override                                public void onClick(DialogInterface dialog, int which) {
                                    finish();
                                }
                            })
                    .setNegativeButton("取消",
                            new DialogInterface.OnClickListener() {
                                @Override                                public void onClick(DialogInterface dialog,
                                                    int which) {  }
                            }).show();
            adialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.argb(255, 0, 153, 0));
            adialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextSize(20);
            adialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.argb(255, 0, 0, 153));
            adialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextSize(20);
        }
        return true;
    }

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pack = getPackageName(); //backup for use after ending fragment        spref = getSharedPreferences("settings", Context.MODE_PRIVATE);
        if (spref.getInt("column",0) == R.id.three) { col = 3; }
        else if (spref.getInt("column", 0) == R.id.four) { col = 4; }
        else if (spref.getInt("column", 0) == R.id.five) { col = 5; }

        num = spref.getInt("number", 32);
        pos = spref.getInt("pos", 0);

        fontSize = fontSize - (col-3)*4; //袂用float運算??若無會當掉,但是模擬器袂。
        for (int j=0; j<num; j++) {
            HashMap<String, Integer> map = new HashMap<String, Integer>();
            map.put("note", new Integer(j+1));
            map.put("second", new Integer(0));
            location.add(j, map);
        }

        grid = (GridView) findViewById(R.id.grid);
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int height = metrics.heightPixels;
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(metrics.widthPixels, (int)(height*0.75));
        grid.setLayoutParams(params);

        grid.setNumColumns(col);

        if (spref.getInt("direction",0) == R.id.verticle) location = transpose(location, col);

        adapter = new GridAdapter(this.getBaseContext(), location, R.layout.gridview_item,
                new String[] {"note", "second"}, new int[] {R.id.main_text, R.id.second_text});

        grid.setAdapter(adapter);
        //grid.setOnTouchListener(new View.OnTouchListener() cannot handle position        grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            long startTime = 0;
            long lastClickTime = 0;
            final int CLICK_PERIOD = 400;

            int lastPos = 0;
            @Override            public void onItemClick(AdapterView parent, View view, int position, long s) {
                startTime = System.currentTimeMillis();

                if (startTime - lastClickTime < CLICK_PERIOD && position == lastPos) {
                    TextView main_text = (TextView) view.findViewById(R.id.main_text);
                    TextView second_text = (TextView) view.findViewById(R.id.second_text);

                    if (location.get(position).get("second") == -1) {
                        // just skip virtual item                    }

                    else if (location.get(position).get("second") == 0) {
                        selected ++;
                        location.get(position).put("second", Integer.valueOf(selected));
                    }

                    else  {
                        selected--;
                        for ( int j=0; j<location.size(); j++) {
                            if (location.get(j).get("second") > location.get(position).get("second")) {
                                location.get(j).put("second", location.get(j).get("second")-1);
                            }
                        }
                        location.get(position).put("second", Integer.valueOf(0));
                    }
                    adapter.notifyDataSetChanged();

                }

                lastClickTime = startTime;
                lastPos = position;
            }
        });
        registerReceiver(mBroadcast, new IntentFilter(MY_MESSAGE));
    }

    @Override    protected void onDestroy() {
        super.onDestroy();
        this.unregisterReceiver(this.mBroadcast);
    }

    static private BroadcastReceiver mBroadcast =  new BroadcastReceiver() {
        private final static String MY_MESSAGE = "tw.cyc.sendmessage";
        @Override        public void onReceive(Context mContext, Intent mIntent) {

            if(MY_MESSAGE.equals(mIntent.getAction())) {
                adapter.notifyDataSetChanged();
                Toast.makeText(mContext, "設定值變更了後APP愛重開才有作用。", Toast.LENGTH_LONG).show();
            }
        }
    };

    @Override    public boolean onCreateOptionsMenu(Menu menu) {
        //參數1:群組id, 參數2:itemId, 參數3:item順序, 參數4:item名稱        menu.add(Menu.NONE, 0, 0, "基本設定");
        menu.add(Menu.NONE, 2, 0, "臨時設定");
        menu.add(Menu.NONE, 1, 0, "使用說明");
        return super.onCreateOptionsMenu(menu);
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        //依據itemId來判斷使用者點選哪一個item        switch(item.getItemId()) {
            case 0:
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                MyDialogFragment frag = new MyDialogFragment();
                frag.show(ft, "tx");
                break;
            case 1:
                help();
                break;
            case 2:
                setNumber();
                break;
            default:
        }

        return super.onOptionsItemSelected(item);
    }

    public ArrayList<HashMap<String, Integer>> transpose(ArrayList<HashMap<String, Integer>> old, int column) {
        ArrayList<HashMap<String, Integer>> trans = new ArrayList<HashMap<String, Integer>>();
        int trow = (int) Math.ceil((double) old.size()/column);
        int moverableRow = (int) Math.ceil((double) old.size()/column) - 2;
        int newnum = old.size();
        int remainder = old.size() % column;    //remainder is 1  first        if ( remainder != 0 && (column - remainder - 1) <= moverableRow) {  //            newnum = num + (column-2 - (remainder-1));
        }
        if (newnum > num) {
            for (int j = 0; j < newnum; j++) {
                HashMap<String, Integer> temp = new HashMap<String, Integer>();
                temp.put("note", Integer.valueOf(trow * (j % column) + (j / column)));
                temp.put("second", Integer.valueOf(0));
                trans.add(j, temp);
                trans.get(j).put("note", Integer.valueOf(trans.get(j).get("note") + 1));
            }
        }
        else {
            int mustChCol = 0;  //zero is first            if (newnum % column == 0) mustChCol = 0;
            else mustChCol = newnum % column + 1;  //0 first            for (int j=0 ; j< newnum; j++) {
                HashMap<String, Integer> temp = new HashMap<String, Integer>();
                if (mustChCol != 0 && j%column >= mustChCol) {  //mustChCol is 0 first, j is 0 first                    //temp.put("note", Integer.valueOf(trow * (j % column) + (j / column) - (j % column - (mustChCol-1)  -  ));                    temp.put("note", Integer.valueOf(trow * (j % column) + (j / column) - (j % column - mustChCol) - 1));
                } else temp.put("note", Integer.valueOf(trow*(j % column) + (j / column)));
                temp.put("second", Integer.valueOf(0));
                trans.add(j, temp);
                trans.get(j).put("note", Integer.valueOf(trans.get(j).get("note") + 1));
            }
        }

        if (remainder > 0 && newnum > num) {
            for (int j = 1; j <= column-1 - remainder; j++) {
                int change = ((trow - 1) - j) * column + (column - 1);  // index 0 begin                trans.get(change).put("note", Integer.valueOf(-1));
                trans.get(change).put("second", Integer.valueOf(-1));
            }
        }

        return trans;
    }

View lastClickView = null;
    public void clear(View v) {
        startTime = System.currentTimeMillis();
        if (startTime - lastClickTime < CLICK_PERIOD && lastClickView == v) {
            for (int j=0; j<location.size(); j++) {  //check if cleared do nothing                if (location.get(j).get("second") > 0) {
                    AlertDialog adialog = new AlertDialog.Builder(this)
                            .setTitle("確定欲總清掉?")
                            .setPositiveButton("確定",
                                    new DialogInterface.OnClickListener() {
                                        @Override                                        public void onClick(DialogInterface dialog, int which) {
                                            selected = 0;
                                            for (int j = 0; j < location.size(); j++) {
                                                if (location.get(j).get("second") != -1)  // -1 is virtual , reserved                                                    location.get(j).put("second", Integer.valueOf(0));
                                            }
                                            adapter.notifyDataSetChanged();
                                        }
                                    })
                            .setNegativeButton("取消",
                                    new DialogInterface.OnClickListener() {
                                        @Override                                        public void onClick(DialogInterface dialog, int which) {
                                        }
                                    }).show();
                    adialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.argb(255, 0, 153, 0));
                    adialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextSize(20);
                    adialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.argb(255, 0, 0, 153));
                    adialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextSize(20);

                    break;
                }
            }
        }
        lastClickTime = startTime;
        lastClickView = v;

    }

    @Override    public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
        //Log.i("value is",""+newVal);
    }

    public void setNumber() {
        final Dialog d = new Dialog(MainActivity.this);
        d.setTitle("NumberPicker");
        d.setContentView(R.layout.dialogview);
        Button b1 = (Button) d.findViewById(R.id.button1);
        Button b2 = (Button) d.findViewById(R.id.button2);
        final NumberPicker np = (NumberPicker) d.findViewById(R.id.numberPicker1);
        np.setMaxValue(50); // max value 100        np.setMinValue(3);   // min value 0        np.setValue(30);
        np.setWrapSelectorWheel(false);
        np.setOnValueChangedListener(this);
        b1.setOnClickListener(new View.OnClickListener()
        {
            @Override            public void onClick(View v) {
                int num = np.getValue();
                location.clear();
                for (int j=0; j<num; j++) {
                    HashMap<String, Integer> map = new HashMap<String, Integer>();
                    map.put("note", new Integer(j+1));
                    map.put("second", new Integer(0));
                    location.add(j, map); selected = 0;
                }
                adapter.notifyDataSetChanged();
                d.dismiss();
            }
        });
        b2.setOnClickListener(new View.OnClickListener()
        {
            @Override            public void onClick(View v) {
                d.dismiss(); // dismiss the dialog            }
        });
        d.show();
    }

    public void help() {
        AlertDialog adialog = new AlertDialog.Builder(this)
                .setTitle("來點名囉--版權佮使用說明")
                .setMessage("1.連紲點才有作用,為防止無小心揤著。\n" +
                        "2.點了的閣點會取消,後壁的攏進一名。\n" +
                        "3.本軟體是自由軟體,歡迎散佈使用。\n" +
                        "4.軟體版本2017.08,適用 android4.3以上。\n" +
                        "台灣軟體自由協會。")
                .setPositiveButton("確定",
                        new DialogInterface.OnClickListener() {
                            @Override                            public void onClick(DialogInterface dialog, int which) {
                            }
                        }).show();

        adialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.argb(255, 0, 153, 0));
        adialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextSize(20);
    }


    public class MyDialogFragment extends DialogFragment {

        @Override        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setStyle(DialogFragment.STYLE_NORMAL, R.style.MY_DIALOG);
        }

        @Override        public void onPause() {
            Intent intent = new Intent();
            intent.setAction(MY_MESSAGE);
            sendBroadcast(intent);
            super.onPause();
        }


        @Override        public void onStart() {
            super.onStart();
            Dialog d = getDialog();
            if (d!=null){
                int width = ViewGroup.LayoutParams.MATCH_PARENT;
                int height = ViewGroup.LayoutParams.MATCH_PARENT;
                d.getWindow().setLayout(width, height);
            }
        }

        @Override        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View root = inflater.inflate(R.layout.my_fragment, container, false);

            column = (RadioGroup) root.findViewById(R.id.column);
            column.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                @Override                public void onCheckedChanged(RadioGroup group, int checkedId) {
                    spref.edit().putInt("column", checkedId).apply();
                    changed = true;
                }
            });
            column.check(spref.getInt("column", 0));

            number = (EditText) root.findViewById(R.id.number);
            number.setText(Integer.toString(spref.getInt("number", 0)));
            number.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    spref.edit().putInt("number", Integer.parseInt(number.getText().toString())).apply();
                    changed = true;
                }
            });

            spinner = (Spinner) root.findViewById(R.id.spinner);
            ArrayAdapter colorList = ArrayAdapter.createFromResource(root.getContext(),
                    R.array.color, android.R.layout.simple_dropdown_item_1line);
            spinner.setAdapter(colorList);
            spinner.setSelection(spref.getInt("pos", 0));
            spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    spref.edit().putInt("pos", position).apply();
                    changed = true;
                }
                @Override                public void onNothingSelected(AdapterView<?> parent) { }
            });

            direction = (RadioGroup) root.findViewById(R.id.direction);
            direction.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                @Override                public void onCheckedChanged(RadioGroup group, int checkedId) {
                    spref.edit().putInt("direction", checkedId).apply();
                    changed = true;
                }
            });
            direction.check(spref.getInt("direction", 0));

            return root;
        }

    }

沒有留言:

張貼留言