我希望有人能帮助我。我创建了一个数独应用程序。我有一个网格视图,它显示列表视图中的字符串文本。我的手机和平板电脑上的网格视图布局有问题;,请参见下面的第 1 和第 2 个屏幕。
我想要做的是设置屏幕,所以网格整齐地显示在数字 1 到 5 的上方。理想情况下,我希望它能够在平板电脑和手机上正确呈现。
在手机上,数独网格的最后一行显示在第一组按钮按钮下方,请参见 firstImage。而在平板电脑上,gridvview 和按钮之间存在巨大差距
到目前为止我所尝试的:我尝试了 android:layout_above btn1。但这切断了数独网格的最后一行,我不得不上下拖动网格才能在手机上看到最后一行。它还导致该应用程序崩溃的手机。不好。
我尝试将框架布局放在相对布局中,并将 gridview 放在其中。但这也根据 layout_above 切断了数独网格的最后一行。
我真正想做的是,在电话上,我想删除或减少网格视图中每个单元格中每个数字上方和下方的填充。由于单元格填充使网格中的每个单元格比它需要的大 2 - 3 倍。这是5英寸手机屏幕上的问题。我尝试了以下方法,但都没有奏效。
如何摆脱 Listview 行中不需要的填充 android:gravity - 没有区别
如何避免linearlayout listSelector =“@null”中imageview和gridview之间的空间 - 没有区别
在 android stretchMode(0)中删除 GridView 中的额外填充;- 一切都消失了。
如何摆脱 Listview 行 view.setMinimumHeight(0);中不需要的填充 - 没有区别。
我也试过 view.setPadding(); 这很有用,因为左侧的填充被删除了,但它没有删除顶部或底部的填充。
view.setPadding(dpToPx(0, parent), 0, 0, 0);
在这个阶段,我对如何推进这一点不知所措,并担心尝试所有这些不同的事情会让我更加困惑。如果有人能指出我正确的方向,我将不胜感激。代码如下所示。
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.example.admin1.sudoku.MainActivity"
android:background="#663399"
tools:showIn="@layout/activity_main">
<Button
android:id="@+id/btn1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn1Label"
android:layout_above="@+id/btn6"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignBottom="@+id/btn2"
/>
<Button
android:id="@+id/btn2"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn2Label"
android:layout_above="@+id/btn7"
android:layout_toLeftOf="@+id/btn8"
android:layout_toStartOf="@+id/btn8" />
<Button
android:id="@+id/btn3"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn3Label"
android:layout_alignTop="@+id/btn2"
android:layout_toRightOf="@+id/btn2"
android:layout_toEndOf="@+id/btn2" />
<Button
android:id="@+id/btn4"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn4Label"
android:layout_alignTop="@+id/btn3"
android:layout_toRightOf="@+id/btn3"
android:layout_toEndOf="@+id/btn3" />
<Button
android:id="@+id/btn5"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn5Label"
android:layout_alignTop="@+id/btn4"
android:layout_toRightOf="@+id/btn4"
android:layout_toEndOf="@+id/btn4" />
<Button
android:id="@+id/btn6"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn6Label"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:id="@+id/btn7"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn7Label"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@+id/btn6"
android:layout_toEndOf="@+id/btn6" />
<Button
android:id="@+id/btn8"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn8Label"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@+id/btn7"
android:layout_toEndOf="@+id/btn7" />
<Button
android:id="@+id/btn9"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn9Label"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@+id/btn3"
android:layout_toEndOf="@+id/btn3" />
<Button
android:id="@+id/btn0"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn0Label"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@+id/btn9"
android:layout_toEndOf="@+id/btn9" />
<Button
android:id="@+id/btnCheck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btnCheckLabel"
android:layout_below="@+id/gridView1"
android:layout_alignTop="@+id/btn5"
android:layout_toRightOf="@+id/btn5"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:id="@+id/btnHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btnHintLabel"
android:layout_alignTop="@+id/btn0"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignLeft="@+id/btnCheck"
android:layout_alignStart="@+id/btnCheck" />
<GridView
android:id="@+id/gridView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="9"
android:columnWidth="0dp"
android:horizontalSpacing="5dp"
android:verticalSpacing="5dp"
android:clipChildren="true"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:background="#C0C0C0"
android:padding="5dp"
android:textSize="12sp"
android:stretchMode="columnWidth"
android:gravity="clip_vertical"
/>
</RelativeLayout>
MainActivity.java
package com.example.admin1.sudoku;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.GridView;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.graphics.Color;
import android.widget.Toast;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import android.content.res.Resources;
import android.media.MediaPlayer;
public class MainActivity extends AppCompatActivity {
// Class that holds the creation of a Sudoku Puzzle
private SudokuPuzzle clsSudoku;
//Variables used throughout the program.
private final int iMaxCells = 81;
private String[] stResult; // Holds the solution to the current puzzle
private int[] iExcluded; // Holds all the blue cells (clues given to the user at the start)
// Placed into List for fast searching
private int iElement;
private boolean blShowResult; // Indicates if the user has clicked Show Result
private boolean blGiveHint; // Indicates if the user has clicked Give Hint
private boolean blSoundOn;
// UI Elements
private View tvCell;
private GridView gridView;
private Menu menu;
private MediaPlayer mp = null;
/* Lists
lstitems holds all the items in the current board including user entries
lstExclude holds all the blue cells (clues given to the user at the start)
adapter
*/
private List<String> lstItems;
private ArrayAdapter<String> adapter ;
private List<Integer> lstExcluded;
public MainActivity() {
stResult = new String[iMaxCells];
blGiveHint = false;
blShowResult = false;
iElement = 0;
blSoundOn = false;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Declare used buttons
Button btn1 = (Button) findViewById(R.id.btn1);
Button btn2 = (Button) findViewById(R.id.btn2);
Button btn3 = (Button) findViewById(R.id.btn3);
Button btn4 = (Button) findViewById(R.id.btn4);
Button btn5 = (Button) findViewById(R.id.btn5);
Button btn6 = (Button) findViewById(R.id.btn6);
Button btn7 = (Button) findViewById(R.id.btn7);
Button btn8 = (Button) findViewById(R.id.btn8);
Button btn9 = (Button) findViewById(R.id.btn9);
Button btn0 = (Button) findViewById(R.id.btn0);
Button btnHint = (Button) findViewById(R.id.btnHint);
Button btnCheck = (Button) findViewById(R.id.btnCheck);
//Creates a new Game
clsSudoku = new SudokuPuzzle();
newGame();
gridView = (GridView) findViewById(R.id.gridView1);
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
if (blGiveHint == true){
blGiveHint = false;
//Initialise any hinted cells back to white
clearCells();
}
if (!blShowResult){
tvCell = gridView.getChildAt(iElement);
try{
tvCell.setBackgroundColor(Color.WHITE);
iElement = position;
tvCell = gridView.getChildAt(iElement);
tvCell.setBackgroundColor(Color.RED);
}
catch(Exception e){
}
}
}
});
gridView.setAdapter(adapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_1, lstItems) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
view.setPadding(dpToPx(0, parent), 0, 0, 0);
view.setMinimumHeight(0);
if (position == iElement && !blShowResult){
view.setBackgroundColor(Color.RED);
}
else if (lstExcluded.contains(position)) {
view.setBackgroundColor(Color.WHITE);
}
else{
view.setBackgroundColor(Color.CYAN);
}
return view;
}
@Override
public boolean isEnabled(int position) {
// Item position which you want to disable.
if (!lstExcluded.contains(position) ) {
return false;
}
else {
return true;
}
}
});
btn1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "1");
adapter.notifyDataSetChanged();
}
}
});
btn2.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "2");
adapter.notifyDataSetChanged();
}
}
});
btn3.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "3");
adapter.notifyDataSetChanged();
}
}
});
btn4.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "4");
adapter.notifyDataSetChanged();
}
}
});
btn5.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "5");
adapter.notifyDataSetChanged();
}
}
});
btn6.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "6");
adapter.notifyDataSetChanged();
}
}
});
btn7.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "7");
adapter.notifyDataSetChanged();
}
}
});
btn8.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "8");
adapter.notifyDataSetChanged();
}
}
});
btn9.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "9");
adapter.notifyDataSetChanged();
}
}
});
btn0.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "");
adapter.notifyDataSetChanged();
}
}
});
btnHint.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
blGiveHint = true;
giveHint();
}
});
btnCheck.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
checkCorrect();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
this.menu = menu;
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
switch(id){
case R.id.new_game:
createNewGame();
return true;
case R.id.show_result:
getResult();
return true;
case R.id.sound_toggle:
setSoundSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// Populate a list for fast searching later
private void populateExcludeList(int[] ipiArray){
lstExcluded.clear();
for (int iCnt = 0; iCnt < ipiArray.length; iCnt++){
lstExcluded.add(ipiArray[iCnt] - 1);
}
Collections.sort(lstExcluded);
}
// Populate a list for fast searching later
private void setBoard(String[] ipstArray){
lstItems.clear();
for (int iCnt = 0; iCnt < ipstArray.length; iCnt++){
lstItems.add(ipstArray[iCnt]);
}
}
// Create a new puzzle
private void newGame(){
String[] stNumbers = new String[iMaxCells];
blShowResult = false;
clsSudoku.swapTwoNumbers();
clsSudoku.swapTwoColumns();
clsSudoku.swapTwoBlocks();
clsSudoku.rotateNintyDegrees();
clsSudoku.clearNumbers();
stNumbers = clsSudoku.getResult("User");
stResult = clsSudoku.getResult("Result");
iExcluded = clsSudoku.getRemoved();
if (lstItems == null) {
lstItems = new ArrayList<String>(Arrays.asList(stNumbers));
}
else {
setBoard(stNumbers);
}
lstExcluded = new ArrayList<Integer>();
populateExcludeList(iExcluded);
iElement = lstExcluded.get(0);
}
private void createNewGame(){
if ( !lstItems.isEmpty() ){
lstItems.clear();
}
newGame();
adapter.notifyDataSetChanged();
}
private void getResult(){
blShowResult = true;
setBoard(stResult);
lstExcluded = new ArrayList<Integer>();
populateExcludeList(iExcluded);
adapter.notifyDataSetChanged();
}
public void giveHint(){
for (int iCnt = 0; iCnt < iMaxCells; iCnt++){
tvCell = gridView.getChildAt(iCnt);
try{
if (lstItems.get(iCnt).equalsIgnoreCase(stResult[iCnt]) == false && blGiveHint == true){
tvCell.setBackgroundColor(Color.RED);
}
else if(lstItems.get(iCnt).equalsIgnoreCase(stResult[iCnt]) && lstExcluded.contains(iCnt) ){
tvCell.setBackgroundColor(Color.WHITE);
}
}
catch(Exception e){
Toast.makeText(this, "Error: " + e.getMessage(),Toast.LENGTH_LONG).show();
}
}
}
public void checkCorrect(){
boolean blErrorFound = false;
int iCntErrors = 0;
int iCntBlanks = 0;
String stMessage = "";
for (int iCnt = 0; iCnt < iMaxCells; iCnt++){
if ( (lstItems.get(iCnt).equalsIgnoreCase("") == true)
){
iCntBlanks = iCntBlanks + 1;
blErrorFound = true;
}
else if((lstItems.get(iCnt).equalsIgnoreCase(stResult[iCnt]) == false) &&
(lstItems.get(iCnt).equalsIgnoreCase("") == false)
){
iCntErrors = iCntErrors + 1;
blErrorFound = true;
}
}
if (!blErrorFound){
stMessage = "Congratulations !!! Your solution is correct";
if (blSoundOn == true){
playSound("congratulations");
}
}
else{
stMessage = "You have " + iCntErrors + " errors and " + iCntBlanks + " squares left to do";
if (blSoundOn == true){
playSound("wrong");
}
}
Toast.makeText(getApplicationContext(), stMessage, Toast.LENGTH_LONG).show();
}
private void clearCells(){
for (int iCnt = 0; iCnt < iMaxCells; iCnt++){
tvCell = gridView.getChildAt(iCnt);
if(lstExcluded.contains(iCnt) ){
tvCell.setBackgroundColor(Color.WHITE);
}
}
}
private void setSoundSettings() {
MenuItem miMenu = menu.findItem(R.id.sound_toggle);
if (blSoundOn) {
blSoundOn = false;
miMenu.setTitle("Turn Sound On");
} else {
blSoundOn = true ;
miMenu.setTitle("Turn Sound Off");
}
}
public void playSound(String stFileName){
int iSoundId;
if (mp != null){
mp.reset();
mp.release();
}
Resources res = getApplicationContext().getResources();
iSoundId = res.getIdentifier(stFileName, "raw", getApplicationContext().getPackageName());
mp = MediaPlayer.create(getApplicationContext(), iSoundId);
mp.start();
}
public int dpToPx(int dp, View v) {
DisplayMetrics displayMetrics = v.getContext().getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
}